【问题标题】:Can't closure return a reference?闭包不能返回引用吗?
【发布时间】:2020-02-29 11:02:28
【问题描述】:
fn main() {
    let a = String::from("foo");
    let f = || &a;
    fn_immut(f);
    println!("{}", a);
}

fn fn_immut<F>(f: F)
               where F: Fn() -> &String
{
    println!("calling Fn closure from fn, {}", f());
}

这段代码无法编译,rustc 告诉我应该像这样添加一个'static

fn fn_immut<F>(f: F)
               where F: Fn() -> &'static String

我试过了,但还是不行。而rustc 还告诉我“这个函数的返回类型包含一个借来的值,但没有可以借用的值”。

我的问题是:在这段代码中,闭包已经在其范围内捕获了变量a 的引用,为什么 rustc 仍然告诉我“它没有借用的价值”?

【问题讨论】:

    标签: rust


    【解决方案1】:

    来自编译器的关键信息确实是缺少返回字符串的闭包的生命周期说明符。由于 trait Fn() -&gt; &amp;String 定义的签名没有任何函数参数,因此编译器无法从中推断返回引用的生命周期。

    error[E0106]: missing lifetime specifier
      --> src/main.rs:10:16
       |
    10 |     F: Fn() -> &String,
       |                ^ help: consider giving it a 'static lifetime: `&'static`
       |
       = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
    

    在此处添加'static 无助于解决问题,因为实际上返回的字符串不会有那个生命周期。需要在fn_immut 中引入一个新的生命周期参数,从中可以转移到F 的约束。

    fn fn_immut<'a, F>(f: F)
    where
        F: Fn() -> &'a String,
    

    您还可以返回一个字符串切片 (&amp;str) 而不是 &amp;String。完整代码:

    fn main() {
        let a = String::from("foo");
        let f = || &*a;
        fn_immut(f);
        println!("{}", a);
    }
    
    fn fn_immut<'a, F>(f: F)
    where
        F: Fn() -> &'a str,
    {
        println!("calling Fn closure from fn, {}", f());
    }
    

    Playground

    【讨论】:

      猜你喜欢
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多