NSA*_*ict 3 initialization lifetime rust
我想为以下结构编写初始化器.
struct Foo {
bar: &Bar
}
Run Code Online (Sandbox Code Playgroud)
它建议使用&T过Box<T>的灵活性,这就是我要为这里.如果没有初始化器,您可以使用这样的结构.
{
let bar = ...;
let foo = Foo { bar: bar };
// use foo
// dealloc bar and foo
}
Run Code Online (Sandbox Code Playgroud)
这有效.但我想&Bar在初始化器中分配.现在显然bar在堆栈上分配将无法工作,因为一旦初始化器返回它就超出了范围.所以我想我可以用Box.
fn new() -> Foo {
let bar = Box::new(...);
Foo { bar: &*bar }
}
Run Code Online (Sandbox Code Playgroud)
这也不起作用,因为我猜我们只是借用价值而不是转移所有权,bar一旦new返回仍然会解除分配.
Box在这种情况下,我是否被迫在结构中使用a ?
注意:需要引用的原因是因为Bar在我的情况下实际上是一个通用特征,因此大小可能会有所不同,这意味着堆栈上的分配将不起作用.
你的问题没有意义.如果要在new方法中构造对象,那么根据定义,您知道类型是什么(因为您正在调用该构造函数),并且您不需要将其视为特征对象.你应该只使用这种类型!
需要引用的原因是因为Bar在我的情况下实际上是一个通用特征,因此大小可以变化,这意味着堆栈上的分配将不起作用.
这不完全正确!如果您想接受参数,并且想要转移所有权,那么您可以简单地将类型限制为您想要的特征:
trait Talker { fn talk(&self); }
struct Dog;
impl Talker for Dog { fn talk(&self) { println!("Woof") }}
struct Cat;
impl Talker for Cat { fn talk(&self) { println!("Meow") }}
struct OwnAGeneric<T: Talker> {
t: T
}
impl<T: Talker> OwnAGeneric<T> {
fn new(t: T) -> OwnAGeneric<T> { OwnAGeneric { t: t } }
fn talk(&self) { println!("I own this:"); self.t.talk(); }
}
fn main() {
let owned_cat = OwnAGeneric::new(Cat);
owned_cat.talk();
}
Run Code Online (Sandbox Code Playgroud)
这应该由编译器单一化,并且基本上与您手动编写代码一样快.这也允许在堆栈上分配所有内容.