Summary:
没有给出该名称的明确原因.然而,这个名字极有可能来自世界parsers,人们"期望"看到一个特定的标记(否则编译失败).
在rustc中,expect
个类似函数的使用早于Option
个函数的使用.这些函数包括expect(p, token::SEMI)
,用于解析分号,expect_word(p, "let")
,用于解析let
关键字.如果未达到预期,编译将失败并显示错误消息.
最终,在编译器中添加了一个实用函数,该函数期望的不是特定的令牌或字符串,而是给定的Option
包含一个值(否则,使用给定的错误消息编译失败).随着时间的推移,它被转移到Option
struct 本身,至今仍保留在那里.
就我个人而言,我觉得这一点都不奇怪.它只是另一个动词,你可以把它和对象联系起来,比如展开、获取或映射它的值.从你的Option
中期待一个值(否则,失败)似乎很自然.
History:
最早的提交记录如下:
https://github.com/rust-lang/rust/commit/b06dc884e57644a0c7e9c5391af9e0392e5f49ac
这将在编译器中添加此函数:
fn expect<T: copy>(sess: session, opt: option<T>, msg: fn() -> str) -> T {
alt opt {
some(t) { t }
none { sess.bug(msg()); }
}
}
据我所知,这是第一个名为"expect"的函数,用于判断Option
.请特别注意commit中的这个示例用例(它实现了对类方法的支持!):
#debug("looking up %? : %?", def, class_doc);
let the_field = expect(tcx.sess,
decoder::maybe_find_item(def.node, class_doc),
{|| #fmt("get_field_type: in class %?, field ID %? not found",
class_id, def)});
如果decoder::maybe_find_item
的结果是None
,编译将失败,并出现给定的错误.
我鼓励您在这个提交中查看解析器代码——还有其他expect
个类似函数的广泛使用:例如expect(p, token::RPAREN)
和expect_word(p, "let")
.在这种环境下,这个新函数的名称几乎显而易见.
最终,该函数的实用性被提取出来,并放在Option
本身中:
https://github.com/rust-lang/rust/commit/e000d1db0ab047b8d2949de4ab221718905ce3b1
看起来像:
pure fn expect<T: copy>(opt: option<T>, reason: str) -> T {
#[doc = "
Gets the value out of an option, printing a specified message on failure
# Failure
Fails if the value equals `none`
"];
alt opt { some(x) { x } none { fail reason; } }
}
值得注意的是,不久之后,终于有了一个名为unwrap_expect
的(附加)函数:
https://github.com/rust-lang/rust/commit/be3a71a1aa36173ce2cd521f811d8010029aa46f
pure fn unwrap_expect<T>(-opt: option<T>, reason: ~str) -> T {
//! As unwrap, but with a specified failure message.
if opt.is_none() { fail reason; }
unwrap(opt)
}
随着时间的推移,它们都被Expect
trait所包含,Option
实现了:
https://github.com/rust-lang/rust/commit/0d8f5fa618da00653897be2050980c800389be82
/// Extension trait for the `Option` type to add an `expect` method
// FIXME(#14008) should this trait even exist?
pub trait Expect<T> {
/// Unwraps an option, yielding the content of a `Some`
///
/// # Failure
///
/// Fails if the value is a `None` with a custom failure message provided by
/// `msg`.
fn expect<M: Any + Send>(self, m: M) -> T;
}
剧透:这种trait 已经不存在了.根据以下内容,它很快被移除:
https://github.com/rust-lang/rust/issues/14008
这或多或少就是我们今天的处境.
我认为最有可能的结论是,expect
作为一个有意义的函数名的使用早于Option
年.考虑到它所做的(期望值或失败),几乎没有理由打破这种模式.