On-Ramp to Rust

Option<T> and null safety

In C, a great many bugs trace back to one value: NULL. A pointer can be NULL to mean nothing here, no result, not found — and the danger is that NULL looks exactly like a valid pointer until you dereference it, at which point your program crashes with a segmentation fault. The trouble is that the type char *p says nothing about whether p might be NULL, so the language never reminds you to check, and one forgotten check is all it takes. Rust removes NULL entirely. There are no null pointers in safe Rust. Instead, the possibility of absence is made explicit in the type with Option<T>.

Option<T> is a type that holds either a value or nothing, and you must say which. It has exactly two shapes: Some(x), meaning there is a value and it is x, and None, meaning there is no value. So where a C function returns a char * that might be NULL, a Rust function returns Option<String> — and now the type itself announces this might be absent. The crucial consequence is that you cannot accidentally use the value as if it were always there. To get at the inner value you have to handle both cases, usually with a match or with helpers like if let Some(x) = opt. The compiler will not let you reach the x in Some(x) without first acknowledging the None possibility, so the forgotten-NULL-check bug becomes a compile error instead of a runtime crash.

Why this matters: the absence of a value is now tracked by the type system rather than left to a convention you might forget. If a function can return nothing, its return type says Option, and every caller is forced by the compiler to deal with the nothing case. This converts a whole class of C's most common crashes — the null-pointer dereference — into errors caught before the program runs. The honest caveat is that Rust does give you escape hatches like opt.unwrap(), which extracts the value and deliberately panics (crashes in a controlled way) if it was None. unwrap is fine for quick code and impossible cases, but using it everywhere just to silence the compiler throws away the very safety Option was meant to provide.

fn first_char(s: &str) -> Option<char> { s.chars().next() // Some(c) if non-empty, else None } match first_char("hi") { Some(c) => println!("first is {c}"), None => println!("empty string"), }

The type says a value may be absent; the compiler makes you handle the None case.

Option does not make absence impossible — it makes it impossible to ignore. opt.unwrap() pulls the value out but panics on None; reaching for unwrap just to quiet the compiler discards the protection Option exists to give.

Also called
OptionSome and Noneno null pointers選項型別可選型別