So you're saying that Option
to you means some enumeration where you choose between N different values, e.g. a species drop-down between Human, Elf, Orc, Gnome, Other.
The main problem with Nullable
is the question of what does Nullable<Nullable<T>>
mean? Is it still just a choice between T
or null
, or is it a choice between T
, null
, and a different null
?
Option<T>
is a simple enum { Some(T), None }
, and as such Option<Option<T>>
is a simple composition and obviously has three possible states, Some(Some(T))
, Some(None)
, and None
.
I think a core misunderstanding here might be that this sentence is completely nonsensical in Rust. There aren't any "null values" in safe Rust the way there are in Java or other OOP-heavy languages. The lack or presence of Option
isn't like a @Nonnull
or @Nullable
annotation. Values aren't manipulated via handles which could be null
, they're used directly. If you wrap a type in Option
, it takes up more space.
The "null pointer optimization" is exactly that, an optimization. It's guaranteed that if you have Option<&T>
, that this has the same representation as a nullable pointer. But this is a completely irrelevant detail to 99% of Rust programs, which only care that Option<X>
is either some value X
or no value. That when the X
value is &T
the Option
is no larger than the nonoptional value doesn't matter except as an optimization or when doing external FFI with languages other than Rust.
Of the things someone learning Rust needs to learn, the naming of Option
is among the least impactful. Learning a language always means learning what names it uses to refer to things, but Rust has much larger differences than just naming. Rust isn't an OOPy language, and trying to apply OOPy thinking to it will only land you in trouble. For better or worse, Rust encourages (and essentially requires) a very different ("data oriented") way of thinking about programming from traditional OOP schools of thought. To that end, forcing people out of that OOPy comfort zone early could even be considered beneficial.
Reversing the order of if let
to flow left to right has been discussed as a possibility. It is very similar to why .await
is postfix, as well. I don't think it's all that likely (assigning names is important to surrounding code, justifying the prefix signaling), but a postfix match
is somewhat likely to happen eventually. With that you'd write
config_max.match {
Some(max) => println!("The maximum is configured to be {max}"),
_ => println!("No maximum is configured"),
};
and I guess there's a rather unlikely possibility that we'd eventually extend that to allow
config_max.match Some(max) {
println!("The maximum is configured to be {max}");
} else {
println!("No maximum is configured");
}