将String :: as_str传递给Option <string> :: map()失败,并出现类型不匹配错误

时间:2019-05-17 23:22:30

标签: rust

此代码中的第二个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

1 个答案:

答案 0 :(得分:2)

问题在于String::as_str期望引用String而不是String本身。 String::as_str的签名是fn as_str(&self) -> &str,因此您可以看到它以selfString)为参考。

要解释该错误消息,请查看“预期”与“找到”。在消息的“预期”部分,我们看到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);这样的东西应该可以工作。