当前位置:  开发笔记 > 编程语言 > 正文

关闭参数的生命周期注释

如何解决《关闭参数的生命周期注释》经验,为你挑选了1个好方法。

我想编译以下代码:

struct Provider {}

impl Provider {
    fn get_string<'a>(&'a self) -> &'a str { "this is a string" }
}

fn main() {
    let provider = Provider{};
    let mut vec: Vec<&str> = Vec::new();

    // PROBLEM: how do I say that this reference s here
    // needs to live as long as vec?
    let fun = |s: &str| {
        vec.push(s);
    };

    fun(provider.get_string());
}

游乐场链接

这是我得到的编译错误:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
 --> src/main.rs:9:22
  |
9 |     let mut vec: Vec<&str> = Vec::new();
  |                      ^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 11:24...
 --> src/main.rs:11:25
  |
11|     let fun = |s: &str| {
  |                         ^
note: ...so that reference does not outlive borrowed content
 --> src/main.rs:12:18
  |
12|         vec.push(s);
  |                  ^
note: but, the lifetime must be valid for the block suffix following statement 2 at 13:6...
 --> src/main.rs:13:7
  |
13|     };
  |       ^
note: ...so that variable is valid at time of its declaration
 --> src/main.rs:11:9
  |
11|     let fun = |s: &str| {
  |         ^^^

Shepmaster.. 7

如果删除所有生命周期注释并让编译器推断完成其工作,您的代码就可以正常工作:

struct Provider;

impl Provider {
    fn get_string(&self) -> &str { "this is a string" }
}

fn main() {
    let provider = Provider;
    let mut vec = Vec::new();

    let mut fun = |s| {
        vec.push(s);
    };

    fun(provider.get_string());
}

简而言之,没有办法明确地引用局部变量的生命周期,只有函数参数.但编译器知道如何做到这一点.

如果你真的需要它,你可以创建一个函数来允许注释生命周期:

fn thing<'a>(provider: &'a Provider) -> Vec<&'a str> {
    let mut vec: Vec<&'a str> = Vec::new();

    {
        let mut fun = |s: &'a str| vec.push(s);

        fun(provider.get_string());
    } // End mutable borrow of `vec`

    vec
}

fn main() {
    let provider = Provider;
    thing(&provider);
}

为什么原始注释会阻止工作?

具体来说,就是这样:

let fun = |s: &str| {
    vec.push(s);
};

这声明了关闭时的新生命周期.使用一个伪造的语法(你不能在闭包参数上声明生命周期),它将等同于:

let fun = <'a> |s: &'a str| {
    vec.push(s);
};

这就是编译器出错的原因:

生命周期不能超过[封闭块]上定义的匿名生命#1

生成的生命周期与生成生命周期之间没有任何联系Provider.将其遗漏允许编译器插入所需但不可用的生命周期.



1> Shepmaster..:

如果删除所有生命周期注释并让编译器推断完成其工作,您的代码就可以正常工作:

struct Provider;

impl Provider {
    fn get_string(&self) -> &str { "this is a string" }
}

fn main() {
    let provider = Provider;
    let mut vec = Vec::new();

    let mut fun = |s| {
        vec.push(s);
    };

    fun(provider.get_string());
}

简而言之,没有办法明确地引用局部变量的生命周期,只有函数参数.但编译器知道如何做到这一点.

如果你真的需要它,你可以创建一个函数来允许注释生命周期:

fn thing<'a>(provider: &'a Provider) -> Vec<&'a str> {
    let mut vec: Vec<&'a str> = Vec::new();

    {
        let mut fun = |s: &'a str| vec.push(s);

        fun(provider.get_string());
    } // End mutable borrow of `vec`

    vec
}

fn main() {
    let provider = Provider;
    thing(&provider);
}

为什么原始注释会阻止工作?

具体来说,就是这样:

let fun = |s: &str| {
    vec.push(s);
};

这声明了关闭时的新生命周期.使用一个伪造的语法(你不能在闭包参数上声明生命周期),它将等同于:

let fun = <'a> |s: &'a str| {
    vec.push(s);
};

这就是编译器出错的原因:

生命周期不能超过[封闭块]上定义的匿名生命#1

生成的生命周期与生成生命周期之间没有任何联系Provider.将其遗漏允许编译器插入所需但不可用的生命周期.

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有