在结构中存储函数特征对象的时间不够长

时间:2016-07-03 20:46:41

标签: rust

我试图在这样的结构中存储两个函数:

struct Example<'a> {
    func1: &'a Fn(f64) -> f64,
    func2: &'a Fn(f64) -> f64,
}

impl<'a> Example<'a> {

    fn new(f1: &'a Fn(f64) -> f64, f2: &'a Fn(f64) -> f64) -> Example<'a> {
        Example {
            func1: f1,
            func2: f2,
        }
    }

    fn test_func(self, x: f64, y: f64) -> f64 {
        (self.func1)(x) + (self.func2)(y)
   }
}


fn main() {
    fn first(x: f64) -> f64 {
        x
    }
    fn second(x: f64) -> f64 {
        x
    }
    let test = Example::new(&first, &second);
    test.test_func(1.0, 2.0);
}

Rust playground

生成以下错误:

borrowed value does not live long enough
    let test = Example::new(&first, &second);
                            ^~~~~
note: reference must be valid for the block suffix following statement 2 at 28:45...
    let test = Example::new(&first, &second);
    test.test_func(1.0, 2.0);
}
note: ...but borrowed value is only valid for the statement at 28:4
    let test = Example::new(&first, &second);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: consider using a `let` binding to increase its lifetime
    let test = Example::new(&first, &second);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: borrowed value does not live long enough
    let test = Example::new(&first, &second);
                                    ^~~~~~
note: reference must be valid for the block suffix following statement 2 at 28:45...
    let test = Example::new(&first, &second);
    test.test_func(1.0, 2.0);
}
note: ...but borrowed value is only valid for the statement at 28:4
    let test = Example::new(&first, &second);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: consider using a `let` binding to increase its lifetime
    let test = Example::new(&first, &second);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我很困惑这是如何生命的问题,因为这两个函数和结构应该在main中共享相同的生命周期。还混淆了为什么编译器的建议似乎与我已有的相同。

1 个答案:

答案 0 :(得分:2)

正如编译器建议的那样(考虑使用let绑定来增加其生命周期)允许代码编译:

fn main() {
    fn first(x: f64) -> f64 {
        x
    }
    fn second(x: f64) -> f64 {
        x
    }

    let x = &first;
    let y = &second;
    let test = Example::new(x, y);

    println!("{}", test.test_func(1.0, 2.0));
}

同样

let x = first;
let y = second;
let test = Example::new(&x, &y);

我相信(但不知道如何证明)问题是必须创建某些东西以使函数指针(fn(f64) -> f64)适应特征对象(&Fn(f64) -> f64)。但是,在new调用中创建它意味着在语句返回时会立即删除它。

这类似于文字引用的情况,它具有相同的错误:

struct Foo<'a>(&'a u8);

fn main() {
    let f = Foo(&4);
    println!("{}", f.0);
}