optional-type
No related notes
Outlinks (0)
No outlinks found
Backlinks (0)
No backlinks found
1 · optional-type#
S: 程序中一个值可能存在,也可能不存在(函数可能返回空、查找可能失败)
C: 传统语言(C/Java/Go)用 null/nil 表示”没有值”,但指针/引用类型默认可空,编译器不强制检查,程序员忘记判空就运行时崩溃(Tony Hoare 称 null 为”十亿美元的错误”)
Q: 如何在编译期就强制处理”值可能不存在”的情况?
A: Optional Type——在类型层面区分”一定有值 T”和”可能没值 Option<T>”,编译器强制你拆开检查后才能使用内部的值
1.1 · 核心思想
把 null check 从”程序员的自觉”变成”编译器的强制”。
T→ 一定有值,直接使用Option<T>/?T→ 可能没值,必须先处理空的情况才能取出值
1.2 · 各语言对照
| 语言 | 语法 | 强制程度 |
|---|---|---|
| Rust | Option<T> | 编译期强制 |
| Zig | ?T | 编译期强制 |
| Swift | T? | 编译期强制 |
| Java | Optional<T> | 库级别,不强制 |
| Go | 无,用 nil + 多返回值 | 不强制 |
1.3 · Rust: Option<T>#
fn find_user(id: u64) -> Option<User> {
// 找到返回 Some(user),没找到返回 None
}
let user = find_user(42);
// user.name; // ❌ 编译不过,Option<User> 不是 User
// ✅ 必须拆开
match user {
Some(u) => println!("{}", u.name),
None => println!("not found"),
}
// ✅ 或者用 if let
if let Some(u) = user {
println!("{}", u.name);
}
对于指针类型,Option<&T> / Option<Box<T>> 编译器会优化成 nullable pointer,零开销。
1.4 · Zig: ?T#
fn findUser(id: u64) ?User {
// 找到返回 user,没找到返回 null
}
const user = findUser(42);
// user.name; // ❌ 编译不过,?User 不是 User
// ✅ 必须用 if 或 orelse 拆开
if (user) |u| {
std.debug.print("{s}\n", .{u.name});
} else {
std.debug.print("not found\n", .{});
}
// ✅ 或者提供默认值
const u = user orelse default_user;
?*T(可选指针)和 C 的 T* 一样大,零开销。