[附注]
Rust 的
?
?
运算符
[附注]
Rust 的
?
?
运算符
Option<T>
Option<T>
是 Rust 里表示“可能有值、可能没有”的类型,只有两种取值:
Some(x)
Some(x)
和
None
None
。在返回
Option
Option
的函数里,表达式
e?
e?
的意思是:
- 如果
ee是Some(x)Some(x),整个e?e?的值就是xx,继续往下执行; - 如果
ee是NoneNone,函数立刻返回NoneNone,后面的代码不再执行。
在
Rust 求值器
step
step
中,
Succ(t1)
Succ(t1)
匹配一个后继项,
step(t1)
step(t1)
返回
Option<Term>
Option<Term>
,表示子项是否存在一步后继。这个分支可以写成两种等价形式:
// 用 ?
Succ(t1) => Some(Succ(Box::new(step(t1)?))),
// 不用 ?,展开写
Succ(t1) => match step(t1) {
Some(t1_) => Some(Succ(Box::new(t1_))),
None => return None,
},
// 用 ?
Succ(t1) => Some(Succ(Box::new(step(t1)?))),
// 不用 ?,展开写
Succ(t1) => match step(t1) {
Some(t1_) => Some(Succ(Box::new(t1_))),
None => return None,
},
例如,读取字符串的首字符,并把 ASCII 小写字母转成大写:
fn first_char_upper(s: &str) -> Option<char> {
let c = s.chars().next()?; // 空字符串时这里直接返回 None
Some(c.to_ascii_uppercase())
}
assert_eq!(first_char_upper("rust"), Some('R'));
assert_eq!(first_char_upper(""), None);
fn first_char_upper(s: &str) -> Option<char> {
let c = s.chars().next()?; // 空字符串时这里直接返回 None
Some(c.to_ascii_uppercase())
}
assert_eq!(first_char_upper("rust"), Some('R'));
assert_eq!(first_char_upper(""), None);
对照
[定义] 一步归约
中的同余规则:E-Succ 说“若 ,则 ”。
step(t1)?
step(t1)?
先去找 ,找到了就拿来搭结论;找不到(前提不成立),结论就推不出来,整个函数返回
None
None
。这正好是“子项不能归约,整个项也不能沿这条规则归约”。
类型检查器
type_of
type_of
里的
type_of(t1)?
type_of(t1)?
也是同样的意思:按照
[定义] 类型与类型判断
的规则,子项没有类型,就无法满足相应构造的定型前提,检查器返回
None
None
。