【问题标题】:How do I return a reference to a closure's argument from the closure?如何从闭包返回对闭包参数的引用?
【发布时间】:2015-04-11 16:02:53
【问题描述】:

我是 Rust 新手,不了解生命周期省略和推理的所有规则。我似乎无法从闭包中将引用返回到参数中,并且这些错误对我知识渊博的人没有多大帮助。

我可以使用带有生命周期注释的适当函数来代替闭包,但无法找到在闭包上注释这些生命周期的方法。

struct Person<'a> {
    name: &'a str,
}

impl<'a> Person<'a> {
    fn map<F, T>(&'a self, closure: F) -> T
        where F: Fn(&'a Person) -> T
    {
        closure(self)
    }
}

fn get_name<'a>(person: &'a Person) -> &'a str {
    person.name
}

fn main() {
    let p = Person { name: "hello" };
    let s: &str = p.map(|person| person.name); // Does not work
    // let s: &str = p.map(get_name);  // Works
    println!("{:?}", s);
}

这是编译器错误:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/main.rs:19:34
   |
19 |     let s: &str = p.map(|person| person.name); // Does not work
   |                                  ^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 19:33...
  --> src/main.rs:19:34
   |
19 |     let s: &str = p.map(|person| person.name); // Does not work
   |                                  ^^^^^^^^^^^
note: ...so that expression is assignable (expected &str, found &str)
  --> src/main.rs:19:34
   |
19 |     let s: &str = p.map(|person| person.name); // Does not work
   |                                  ^^^^^^^^^^^
note: but, the lifetime must be valid for the method call at 19:18...
  --> src/main.rs:19:19
   |
19 |     let s: &str = p.map(|person| person.name); // Does not work
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that pointer is not dereferenced outside its lifetime
  --> src/main.rs:19:19
   |
19 |     let s: &str = p.map(|person| person.name); // Does not work
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^

这里发生了什么,如何更改闭包以使其正常工作?

【问题讨论】:

  • 完成 :) 我认为这个问题还没有完全回答。特别是为什么函数和闭包的行为不同,以及编译器错误中究竟引用了哪些冲突的生命周期要求。

标签: closures rust lifetime


【解决方案1】:

我想我将Person 的引用生命周期与结构的生命周期参数(&amp;str 引用)混淆了。这样编译:

struct Person<'a> {
    name: &'a str,
}

impl<'a> Person<'a> {
    fn map<F, T>(&self, closure: F) -> T
        where F: Fn(&Person<'a>) -> T
    {
        closure(self)
    }
}

fn get_name<'a>(person: &Person<'a>) -> &'a str {
    person.name
}

fn main() {
    let p = Person { name: "hello" };
    println!("{:?}", p.map(|person| person.name));
    println!("{:?}", p.map(get_name));
}

我不确定我对生命周期注释的理解是否正确,也许其他人可以挑选出上面的编译器错误。语言非常混乱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多