在使用嵌套泛型创建枚举时,为什么会出现“溢出”错误?

时间:2018-05-27 07:10:03

标签: generics rust

我需要一个在枚举中需要嵌套泛型的结构。这是一个最小的例子:

enum T<A> {
    S(A),
    M(Box<T<Vec<A>>>),
}

fn main() {
    let t = T::M(
        Box::new(
            T::M(
                Box::new(
                    T::S(vec![vec![1], vec![2], vec![3]])
                )
            )
        )
    );
}

编译器失败并显示错误:

overflowed on T<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<std::vec::Vec<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

为什么会发生这种情况,有什么方法吗?

1 个答案:

答案 0 :(得分:2)

首先,您没有包含整个错误消息。您应该尽可能多地包含错误,而不仅仅是它的一小部分。作为参考,错误是:

error[E0320]: overflow while adding drop-check rules for T<i32>
 --> src/main.rs:7:9
  |
7 |     let t = T::M::<i32>(
  |         ^
  |
  = note: overflowed on T<std::vec::Vec<..<std::vec::Vec<i32>>..>>

错误本身告诉您问题:编译器无法生成T类型的丢弃代码。考虑编译器需要做什么:为了销毁类型T<X>的值,它需要能够销毁它的任何变体。这意味着代码要销毁X(针对S变体),代码要销毁Box<T<Vec<X>>>(针对M变体)。

要销毁Box<T<Vec<X>>>,它需要代码来销毁T<Vec<X>>。因此,为了销毁T<X>,编译器还必须生成用于销毁T<Vec<X>>的代码。

因此,为了销毁T<Vec<X>>,编译器还必须生成用于销毁T<Vec<Vec<X>>>的代码。

因此,为了销毁T<Vec<Vec<X>>>,编译器还必须生成用于销毁T<Vec<Vec<Vec<X>>>>的代码。

因此,为了销毁T<Vec<Vec<Vec<X>>>>,编译器还必须生成用于销毁T<Vec<Vec<Vec<Vec<X>>>>>的代码。

无限广告。编译器永远不能停止需要为无限长的类型序列生成丢弃代码,因此它放弃了。在任何破坏泛型类型取决于能够破坏其更复杂版本的情况下都会发生这种情况。

解决方案是不使用T<Vec<A>>。我不知道你会怎么做,因为我不知道你想做什么。也许有更多变种?也许使用Vec<T<A>>?也许让M的paylod成为一个类型参数?