Go nil pointers vs Rust Option: impact on signatures and safety
Tests encoding of absence. Go nil means any pointer may be null, pushing checks to runtime; Rust Option<T> forces compile-time handling. Strong answers cover signatures, validity, and NPO. Red flag: calling Option syntactic sugar for null.
WHAT THIS TESTS: The interviewer wants to see if you understand the difference between implicit nullability and explicit algebraic data types, and how that choice ripples through API design, compiler guarantees, and runtime safety. This is fundamentally about whether absence is representable in every pointer type or isolated in a specific sum type, often called the billion-dollar mistake.
A GOOD ANSWER COVERS: First, function signatures. In Go, any pointer or interface value can be nil, so the signature itself does not tell the caller whether null is expected; documentation and convention carry that burden. In Rust, a function returning T promises a valid reference, while Option<T> explicitly signals potential absence, and the caller must handle both variants. Second, compile-time guarantees. Go defers nil safety to runtime; dereferencing a nil pointer panics. Rust's borrow checker plus exhaustive pattern matching ensures you cannot extract the inner value without accounting for None, eliminating null-dereference at compile time. Third, references versus pointers. Rust references are always valid and non-null by construction; Option<Box<T>> or Option<&T> is the only way to express nullability. Go pointers are just addresses and carry no lifetime or validity guarantees. Fourth, ergonomics and optimization. Mention the null pointer optimization: Option<Box<T>> or Option<&T> has the same size as the raw pointer because None is encoded as the null bit pattern, so the abstraction is zero-cost. Also mention the question-mark operator for propagating Option through call stacks without boilerplate.
COMMON WRONG ANSWERS: Saying Option<T> is just a nullable pointer with nicer syntax misses the semantic guarantee that bare references can never be null. Claiming Go can enforce non-null pointers at compile time is false. Asserting that Option always adds memory overhead ignores the null pointer optimization. Confusing Rust references with Go pointers by saying both are nullable is incorrect; &T in Rust is never null.
LIKELY FOLLOW-UPS: How does Rust's Result<T, E> compare to Go's multiple return values? When would you use Option<&T> versus Option<Box<T>>? How does the Option niche optimization work for enums or nonzero integers? In Go, how do nil interfaces differ from nil pointers, and why is that a common source of bugs?
ONE CONCRETE EXAMPLE: Consider a function that looks up a user by ID. In Go, func FindUser(id int) *User returns a pointer that may be nil, and the caller can forget to check, leading to a runtime panic on u.Name. In Rust, fn find_user(id: u64) -> Option<&User> returns an enum; the compiler rejects code that tries to use the reference without first matching on Some(user) or using unwrap, which forces an explicit decision about the absent case.
Read the original → doc.rust-lang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.