生锈中明显的生命周期错误

时间:2014-12-03 17:53:03

标签: enums rust lifetime object-lifetime

我有一个我要使用的生锈枚举,但是我收到了错误;

error: explicit lifetime bound required
numeric(Num),
        ~~~

有问题的枚举:

enum expr{
   numeric(Num),
   symbol(String),
}

我认为我不明白这里借的是什么。我的意图是Num或String与包含expr的生命周期相同,允许我从函数返回它们。

1 个答案:

答案 0 :(得分:8)

错误消息有点误导。 Num是一个特征,它是一个动态大小的类型,因此如果没有某种间接(引用或Box),您就无法获得它的值。这样做的原因是简单的;问问自己一个问题:枚举值必须有多大(以字节为单位)expr?它当然至少与String一样大,但Num呢?任意类型都可以实现这个特性,所以为了使声音expr必须具有无限大小!

因此,您只能将traits用作类型的某种指针:&NumBox<Num>。指针总是有固定的大小,特征对象是&#34;胖&#34;指针,在其中保留其他信息以帮助进行方法调度。

此外,traits通常用作泛型类型参数的边界。因为泛型是单形的,所以它们在编译代码中变成静态类型,因此它们的大小总是静态知道的,并且它们不需要指针。使用泛型应该是默认方法,只有当你知道泛型为什么不能为你工作时,你才应该切换到特质对象。

这些是您的类型定义的可能变体。使用泛型:

enum Expr<N: Num> {
    Numeric(N),
    Symbol(String)
}

通过参考特征对象:

enum Expr<'a> {  // '
    Numeric(&'a Num + 'a),
    Symbol(String)
}

带框的Trait对象:

enum Expr {
    Numeric(Box<Num + 'static>),  // ' // I used 'static because numbers usually don't contain references inside them
    Symbol(String)
}

您可以在the official guide中阅读有关泛型和特征的更多信息,但目前它缺乏有关特质对象的信息。请问你是否理解不了解。

<强>更新

中的

'a

enum Expr<'a> {  // '
    Numeric(&'a Num + 'a),
    Symbol(String)
}

是一个生命周期参数。它定义了Numeric变体中引用和特征对象内部的生命周期。 &'a Num + 'a是一种类型,您可以将其视为&#34;引用后面的特征对象,其生命周期至少与'a一样长,其中的引用也至少与{{1一样长}}&#34 ;.也就是说,首先,您将'a指定为参考生命周期:'a,其次,您指定特征对象内部的生命周期:&'a。后者是必需的,因为traits可以实现任何类型,包括其中包含引用的类型,所以你需要将这些引用的最小生命周期也放入trait对象类型,否则借用检查不能正确地使用特征对象。

Num + 'a情况非常相似。 Box是#34;堆分配框内的特征对象,其中包含引用,其中至少与Box<Num + 'static>&#34;一样长。 'static类型是堆分配的拥有数据的智能指针。因为它拥有它拥有的数据,所以它不需要像引用那样的生命周期参数。但是,特征对象仍然可以在其中包含引用,这就是为什么仍然使用Box的原因;我只是选择使用Num + 'a生命周期而不是添加另一个生命周期参数。这是因为数字类型通常很简单,并且内部没有引用,它等同于'static绑定。如果你愿意,你可以自由添加一个生命周期参数。

请注意,所有这些变体都是正确的:

'static

即使这是正确的,&'a SomeTrait + 'a &'a SomeTrait + 'static Box<SomeTrait + 'a> // ' Box<SomeTrait + 'static> 'a不同的生命周期参数:

'b

尽管这很少有用,因为&'a SomeTrait + 'b 必须至少与'b一样长(否则特性对象的内部可能会在它本身仍处于活动状态时失效),所以你可以这样做好好使用'a