I’m not a fan of the Default
trait, because it has next to no semantics. It is nowhere defined what the ‘default’ value is supposed to actually represent. Let’s look through the list of implementations:
- For number types (integers and floats) it’s zero.
- For
char
, it’s'\0'
, i.e. U+0000;char
does not have defined addition or multiplication, so this isn’t ‘zero’ in the same sense as above. - For
Option<_>
, it’sNone
. (I can imagineSome(0)
to be more useful starting value in some situations, e.g. if you’re using theNone
variant as an improptu NaN-like value.) - For
str
and slices, it’s the empty slice, and likewise for their growable equivalents:Vec
andString
. - More generally, for containers that can hold any number of items, it’s an appropriate empty container.
- For
Mutex<_>
,RwLock<_>
,ManuallyDrop<_>
, it’s the default value of the underlying type, if it exists. - For
Rc
/Arc
, it’s a singly-referenced default of the underlying type, but forWeak
, it’s a ‘stillborn’ weak pointer with no backing storage. - For
Cow
, it’s a default owned value, even if the borrowed variant implementsDefault
as well (which I imagine would be more lightweight.)
In a generic setting, things are more murky: the ‘default’ value cannot be said to have any particular properties. Is it the smallest possible value? (True for char
and unsigned integers; sorta-true for containers; false for signed integers and floating-point.) Is it the identity element of +
? (True for number types, Vec
and String
.) Does it represent ‘a lack of a value’, whatever it may mean? (True for containers, Weak
and Option
; false for floating-point types, since they the default isn’t a NaN.)
These examples have rather little to do with each other, other than some vague handwave-y notion of ‘zero’ or ‘emptiness’ (and delegating to the wrapped type). It may be what you need most of the time, but that’s primarily because you already know what the concrete type is in a given situation and what you need it for. With its semantics so nebulous, Default
seems useful as little more than a typing aid.
These questions will be even more pertinent for the proposed is_default
method: when you know that a given value is the ‘default’, what can you really say about it? As I point out, it’s not all that much; but I fear some people are going to assume more things about it than is actually guaranteed anyway (I have already seen someone use Default::default()
as a generic zero), which means the proposed functionality is at risk of becoming a correctness hazard.