代码之家  ›  专栏  ›  技术社区  ›  Tedil

为什么编译器会推断一个trait及其实现的不同生存期?

  •  4
  • Tedil  · 技术社区  · 8 年前

    我当前正在使用 rustlearn 评估不同的分类模型。我遇到的问题基本上归结为:

    trait Foo<T> {
        fn bar(&self, x: T);
    }
    
    struct Baz;
    
    struct Smth;
    
    impl<'a> Foo<&'a Smth> for Baz {
        fn bar(&self, x: &Smth) {}
    }
    
    fn main() {
        let some_foo: Box<Baz> = Box::new(Baz {});  // ok
        // let some_foo: Box<Foo<&Smth>> = Box::new(Baz {});  // not ok
        let x = Smth {};
        some_foo.bar(&x);
    }
    

    虽然可以键入 some_foo 像 Box<Baz> ,无法使用 Box<Foo<&Smth>> 相反,因为它会导致编译器抱怨 &x 被丢弃(在 main )仍在借用时(在 bar ). 我认为这是因为 x 已创建 之后 some\u foo 因此 x个 被丢弃 之前 some\u foo . 移动的创建 x个 在创建 some\u foo 将是一个解决方案;但我们假设这是不可能的。

    我仍然不太明白为什么代码对 some_foo: Box<Baz> 但不是为了 some_foo: Box<Foo<&Smth>> . 编译器不知道的是什么(否则就不需要抱怨)?


    ¹因为您有一组希望交叉验证的模型,即。 model.fit(x, y) 哪里 x, y 是较大 (X, Y) .

    1 回复  |  直到 8 年前
        1
  •  3
  •   Stefan    8 年前

    装箱的trait对象需要使用所有生存期来引用 Smth :

    let some_foo: Box<for<'a> Foo<&'a Smth>> = Box::new(Baz {});
    

    也许其他人可以解释为什么编译器无法派生工作生命周期:)

    推荐文章