enums - Rust 中的显式生命周期错误

标签 enums rust lifetime object-lifetime

我有一个我想使用的 Rust 枚举,但是我收到了错误;

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

有问题的枚举:

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

我想我不明白这里借用了什么。我的意图是让 Num 或 String 与包含的 expr 具有相同的生命周期,从而允许我从函数中返回它们。

最佳答案

错误信息有些误导。 Num是一个特征,它是一个动态大小的类型,所以如果没有某种间接(引用或 Box ),你不能拥有它的值。这样做的原因是简单的;只问自己一个问题:什么大小(以字节为单位)expr枚举值必须有?它肯定至少和String一样大,但是 Num 呢? ?任意类型都可以实现这个特性,所以为了健全 expr必须有无限大!

因此,您可以仅通过某种指针将特征用作类型:&NumBox<Num> .指针始终具有固定大小,特征对象是“胖”指针,在其中保留额外信息以帮助方法分派(dispatch)。

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

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

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

通过引用的特征对象:

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

带有框的特征对象:

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是一种类型,您可以将其理解为“至少与 'a 一样长的引用背后的特征对象,其中的引用也至少与 'a 一样长”。也就是说,首先,您指定 'a作为引用生命周期:&'a ,其次,您指定特征对象内部的生命周期:Num + 'a .后者是必需的,因为可以为任何类型实现特征,包括其中包含引用的类型,因此您也需要将这些引用的最短生命周期放入特征对象类型中,否则借用检查将无法与特征对象一起正常工作。

Box情况非常相似。 Box<Num + 'static>是“堆分配框中的特征对象,其中包含至少与 'static 一样长的引用”。 Box type 是堆分配的拥有数据的智能指针。因为它拥有它持有的数据,所以它不需要像引用那样的生命周期参数。但是,trait 对象仍然可以在其中包含引用,这就是为什么 Num + 'a仍在使用;我只是选择使用 'static lifetime 而不是添加另一个生命周期参数。这是因为数值类型通常很简单,内部没有引用,相当于'static。边界。当然,如果需要,您可以自由添加生命周期参数。

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

&'a SomeTrait + 'a
&'a SomeTrait + 'static
Box<SomeTrait + 'a>  // '
Box<SomeTrait + 'static>

即使这是正确的,'a'b作为不同的生命周期参数:

&'a SomeTrait + 'b

尽管这很少有用,因为 'b必须至少与 'a 一样长(否则 trait 对象的内部可能会在它本身仍然存在时失效),所以你也可以使用 &'a SomeTrait + 'a .

关于enums - Rust 中的显式生命周期错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27278401/

相关文章:

rust - 如何将计算9位位掩码中1的个数的C函数转换为Rust?

rust - 在字符串上创建闭包返回迭代器

rust - Cargo 是否依赖于从源代码构建 Cargo 本身?

rust - 是否可以专注于静态生命周期?

rust - 生命周期问题和实现克隆

python - 如何正确记录 python 枚举元素?

ios - 如何从 iOS 中通过解析 JSON 响应获得的 NSDictionary 中提取枚举值

enums - 工厂模式: Enum Parameter vs Explicit Method Name?

java - 枚举中的方法

generics - 如何将 "Encodable"绑定(bind)到类型参数?