我有一个我要使用的生锈枚举,但是我收到了错误;
error: explicit lifetime bound required
numeric(Num),
~~~
有问题的枚举:
enum expr{
numeric(Num),
symbol(String),
}
我认为我不明白这里借的是什么。我的意图是Num或String与包含expr的生命周期相同,允许我从函数返回它们。
答案 0 :(得分:8)
错误消息有点误导。 Num
是一个特征,它是一个动态大小的类型,因此如果没有某种间接(引用或Box
),您就无法获得它的值。这样做的原因是简单的;问问自己一个问题:枚举值必须有多大(以字节为单位)expr
?它当然至少与String
一样大,但Num
呢?任意类型都可以实现这个特性,所以为了使声音expr
必须具有无限大小!
因此,您只能将traits用作类型的某种指针:&Num
或Box<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
。