此代码中的第二个map
语句无法编译。
fn main() {
let hello = Some("hello");
let _switcheroo = hello.map(str::to_string); //ok
let hello = Some("hello".to_string());
let _switcheroo = hello.map(String::as_str); //not ok
}
错误是:
error[E0631]: type mismatch in function arguments
--> src/main.rs:6:29
|
6 | let _switcheroo = hello.map(String::as_str); //not ok
| ^^^
| |
| expected signature of `fn(std::string::String) -> _`
| found signature of `for<'r> fn(&'r std::string::String) -> _`
我希望借用一些已移动的数据时出错。这个错误想说什么?
这确实可以编译:
let hello = Some("hello".to_string());
let _switcheroo = hello.as_ref().map(String::as_str); //ok
答案 0 :(得分:2)
问题在于String::as_str
期望引用String
而不是String
本身。 String::as_str
的签名是fn as_str(&self) -> &str
,因此您可以看到它以self
(String
)为参考。
要解释该错误消息,请查看“预期”与“找到”。在消息的“预期”部分,我们看到fn(std::string::String) -> _
,因此它期望一个函数接受std::string::String
(即String
)并返回一些不相关的类型(_
) 。但是,在消息的“找到”部分中,我们找到了for<'r> fn(&'r std::string::String) -> _
。这很难理解,因为它使用了Rust代码中很少见到的想法。
for<'r>
部分意味着该函数在生命周期方面应该是通用的。它应该接受任何生存期,并带有该生存期的String
。输出类型也可以具有给定的寿命。通常,像这样的函数具有像fn foo(x: &T) -> &U
这样的签名,并且生存期是隐式添加的。这就是String::as_str
的意思。
修复代码的一种方法是确保将引用传递给map
。像let _switcheroo = hello.as_ref().map(String::as_str);
这样的东西应该可以工作。