Rust.expect()是 Result/Option 空间中最令人惊讶的名字之一。虽然unwrap有道理——Result通过“解包”从 a 中获取一个值——但expect出奇地违反直觉(对我来说)。
由于 Rust 的大部分内容都受到函数式编程语言约定的启发,我一直假设这是“对默默无闻的奇怪敬意”的另一个例子,但是当我问鸭子时,它无法为我找到答案。
所以,我放弃了。为什么是.expect()Rust.unwrap_or_panic_with_this_message()函数的名称?这是对另一种功能语言中的功能的引用吗?它是 Tcl 的反手阴影(或补充)吗?Mozilla 熬夜太多,Espresso 太多的结果?
标准库中这个勇敢(但凶猛!)的小成员的词源是什么?
GMa*_*ckG 22
Summary:
No explicit reason for the name is given. However, it is incredibly likely the name comes from the world of parsers, where one "expects" to see a particular token (else the compilation fails).
Within rustc, the use of expect-like functions long predate use within Option. These are functions like expect(p, token::SEMI) to expect to parse a semicolon and expect_word(p, "let") to expect to parse the let keyword. If the expectation isn't met, compilation fails with an error message.
Eventually a utility function was added within the compiler that would expect not a specific token or string, but that a given Option contained a value (else, fail compilation with the given error message). Over time this was moved to the Option struct itself, where it remains today.
Personally, I don't find it unusual at all. It's just another verb you can do to the object, like unwrapping or taking or mapping its value. Expecting a value (else, fail) from your Option seems quite natural.
History:
The oldest commit of note is the following:
https://github.com/rust-lang/rust/commit/b06dc884e57644a0c7e9c5391af9e0392e5f49ac
Which adds this function within the compiler:
fn expect<T: copy>(sess: session, opt: option<T>, msg: fn() -> str) -> T {
alt opt {
some(t) { t }
none { sess.bug(msg()); }
}
}
Run Code Online (Sandbox Code Playgroud)
As far as I can tell, this is the first function named "expect" that deals with inspecting an Option. Observe in particular this example use-case within the commit (which was implementing support for class methods!):
#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)});
Run Code Online (Sandbox Code Playgroud)
If the result of decoder::maybe_find_item is None, compilation will fail with the given error.
I encourage you to look at the parser code in this commit - there is extensive use of other expect-esque functions: e.g., expect(p, token::RPAREN) and expect_word(p, "let"). The name of this new function is almost obvious in this environment.
Eventually, the utility of this function was extracted and placed within Option itself:
https://github.com/rust-lang/rust/commit/e000d1db0ab047b8d2949de4ab221718905ce3b1
Which looked like:
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; } }
}
Run Code Online (Sandbox Code Playgroud)
It's worth noting that sometime later, there was eventually an (additional) function named unwrap_expect added in:
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)
}
Run Code Online (Sandbox Code Playgroud)
Over time these were both subsumed by an Expect trait, which Option implemented:
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;
}
Run Code Online (Sandbox Code Playgroud)
Spoiler for that TODO: that trait no longer exists. It was removed shortly after per:
https://github.com/rust-lang/rust/issues/14008.
More or less this is where we are at today.
I think the most likely conclusion is that the use of expect as a meaningful function name long predates its use in Option. Given it says what it does (expect a value or fail) there is little reason to break the pattern.
| 归档时间: |
|
| 查看次数: |
681 次 |
| 最近记录: |