无法对装箱的特征对象调用方法,因为该方法的寿命不足

时间:2018-10-16 15:21:44

标签: rust lifetime

我想编写一个函数,该函数解析一个字符串并返回实现trait对象的多个结构之一,该特征对象允许分发对实现结构的引用。用例是从配置文件中读取字符串,以确定使用哪种实现。代码如下:

trait Foo<'a> {
    fn get(&'a self) -> &'a i32;
}

struct Bar {
    data: i32,
}

impl<'a> Foo<'a> for Bar {
    fn get(&'a self) -> &'a i32 {
        &self.data
    }
}

struct Baz {
    data: i32,
}

impl<'a> Foo<'a> for Baz {
    fn get(&'a self) -> &'a i32 {
        &self.data
    }
}

fn get_foo(foo: &str) -> Box<dyn Foo> {
    let split = foo.splitn(2, "+").collect::<Vec<_>>();
    let data = i32::from_str_radix(split[1], 10).unwrap();

    if foo.starts_with("bar") {
        Box::new(Bar { data })
    } else {
        Box::new(Baz { data })
    }
}

fn main() {
    let foo = get_foo("bar+0");
    println!("Foo: {}", foo.get());
}

但是,当我这样做时,会出现此错误:

error[E0597]: `*foo` does not live long enough
  --> src/main.rs:38:25
   |
38 |     println!("Foo: {}", foo.get());
   |                         ^^^ borrowed value does not live long enough
39 | }
   | - `*foo` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

这可以在Rust中做吗?

1 个答案:

答案 0 :(得分:0)

感谢@Shepmaster指出,特质对象上的生存期并非可行之路。将生存期移至单个方法(在此示例中可以忽略),效果很好:

trait Foo {
    fn get(&self) -> &i32;
}

struct Bar {
    data: i32,
}

impl Foo for Bar {
    fn get(&self) -> &i32 {
        &self.data
    }
}

struct Baz {
    data: i32,
}

impl Foo for Baz {
    fn get(&self) -> &i32 {
        &self.data
    }
}

fn get_foo(foo: &str) -> Box<dyn Foo> {
    let split = foo.splitn(2, "+").collect::<Vec<_>>();
    let data = i32::from_str_radix(split[1], 10).unwrap();

    if foo.starts_with("bar") {
        Box::new(Bar { data })
    } else {
        Box::new(Baz { data })
    }
}

fn main() {
    let foo = get_foo("bar+0");
    println!("Foo: {}", foo.get());
}