许多编程语言允许使用 null 值,这会导致运行时的 null 指针解引用错误。在 Rust 中,引入了通用类型 Option<T> 来明确表示可选值,这增强了安全性,并且迫使程序员考虑缺失值的情况。
缺失值(例如,搜索结果未找到)通常会导致运行时错误,如果没有在类型中反映出这一点的话。安全且明确地管理空值的情况可以减少 bug 的数量。
类型 Option<T> 实现为一个具有两个变体的枚举:Some(T)(存在值)和 None(缺少值)。这使得编译器强制程序员考虑这两种情况。任何没有显式检查的可选值使用都会导致编译错误。
代码示例:
fn divide(a: i32, b: i32) -> Option<i32> { if b == 0 { None } else { Some(a / b) } } let res = divide(6, 3); match res { Some(result) => println!("结果: {}", result), None => println!("除以零!"), }
关键特性:
Option<T> 是零成本抽象吗,还是每个 Option 变量占用更多空间?
是的,在大多数情况下,Option<T> 是零成本的,当类型 T 不能接受 "null" 值时(例如,引用类型或 Box<T>)。Rust 采用 "nullable pointer optimization" 进行优化,额外的内存并不需要。
let value: Option<&u32> = None; // 不会占用比普通引用更多空间。
可以毫无顾忌地使用 unwrap 吗?
不可以,unwrap() 在值为 None 时会导致 panic。只有在确认值存在的情况下才可以使用,或者选择使用 unwrap_or、unwrap_or_else,或模式匹配。
Option 与引用 (&T, Option<&T>) 有何不同?
引用始终指向一个存在的值。如果值缺失,则需要使用 Option<&T> 来显式反映“可能什么都没有”。使用 Option 而不是直接引用可以防止出现空指针竞态条件。
函数通过 Option 返回搜索结果,但调用代码使用 unwrap,确信总有结果。实际上在缺少值时,程序在生产环境中崩溃。
优点:
缺点:
代码使用 match 处理 Option,所有情况都明确记录并覆盖了测试。
优点:
缺点: