Rust 创建链表时出现意外堆栈溢出

Rust 创建链表时出现意外堆栈溢出,rust,Rust,我一直试图通过扩展 我已经编写了一个构造函数,将泛型向量转换为链表,但是如果向量足够大,使用它会导致堆栈溢出。这让我感到困惑,因为我认为链表是在堆上创建的,因为列表中的每个元素都有一个包含下一个元素的自有框 Rust是我在担心内存管理时使用的第一种语言,所以我有点迷路了。如能解释,将不胜感激。谢谢 我的代码仅被截断为相关gubbins: use std::mem::swap; enum ListItem<T> { Node(T, Box<ListItem<T&

我一直试图通过扩展

我已经编写了一个构造函数,将泛型向量转换为链表,但是如果向量足够大,使用它会导致堆栈溢出。这让我感到困惑,因为我认为链表是在堆上创建的,因为列表中的每个元素都有一个包含下一个元素的自有框

Rust是我在担心内存管理时使用的第一种语言,所以我有点迷路了。如能解释,将不胜感激。谢谢

我的代码仅被截断为相关gubbins:

use std::mem::swap;

enum ListItem<T> { 
    Node(T, Box<ListItem<T>>), 
    Cap 
}

impl <T> ListItem<T> {
    fn append(&mut self, x: T) {
        match *self {
            Node(_, ref mut a@box Cap) => *a = box Node(x, box Cap),
            Node(_, ref mut a@box Node(_, _)) => a.append(x),
            Cap => {
                let mut n = Node(x, box Cap);
                swap(&mut n, self);
            }
        };
    }
}

impl <T: Clone> ListItem<T> {
    fn new_from_vec(x: &mut Vec<T>) -> ListItem<T>{
        let mut l = Cap;
        for v in x.iter() {
            l.append((*v).clone());
        }
        return l;
    }
}

fn main() {
    let mut v: Vec<int> = vec![];

    for n in range(1i, 500001) {
        v.push(n);
    }

    println!("Done creating vector.");

    let x = ListItem::new_from_vec(&mut v);

    println!("Done creating linked list.");
}
使用std::mem::swap;
枚举列表项{
节点(T,盒),
帽子
}
impl列表项{
fn追加(&mut self,x:T){
匹配自我{
节点(u,ref muta@boxCap)=>*a=箱节点(x,箱盖),
节点(u,ref muta@box节点(,))=>a.append(x),
上限=>{
设mut n=节点(x,箱盖);
交换(&M)n,自交换;
}
};
}
}
impl列表项{
fn新的\u来自\u vec(x:&mut vec)->ListItem{
设mut l=Cap;
对于x.iter()中的v{
l、 追加(*v.clone());
}
返回l;
}
}
fn main(){
让mut v:Vec=Vec![];
适用于范围内的n(1i,500001){
v、 推(n);
}
println!(“创建向量完成”);
设x=ListItem::new_from_vec(&mut v);
println!(“创建链接列表完成”);
}

它打印
Done creating vector.
,然后打印
task''在进入下一个
println之前溢出了堆栈

堆栈溢出通常是递归深入的标志。如果仔细查看代码,您可能会发现递归:

impl <T> ListItem<T> {
    fn append(&mut self, x: T) {
        match *self {
            Node(_, ref mut a@box Cap) => *a = box Node(x, box Cap),
            Node(_, ref mut a@box Node(_, _)) => a.append(x),       // <---
            Cap => {
                let mut n = Node(x, box Cap);
                swap(&mut n, self);
            }
        };
    }
}
impl列表项{
fn追加(&mut self,x:T){
匹配自我{
节点(u,ref muta@boxCap)=>*a=箱节点(x,箱盖),
节点(u,ref muta@box节点(,))=>a.append(x),//{
设mut n=节点(x,箱盖);
交换(&M)n,自交换;
}
};
}
}
这意味着,对于列表中已经存在的每个元素,您将在堆栈上创建一个新的函数框架(除非编译器对其进行优化),对于足够数量的元素,该框架将决定性地溢出堆栈


为了避免溢出,您可以切换到迭代版本(使用循环)。

堆栈溢出通常是递归深入的标志。如果仔细查看代码,您可能会发现递归:

impl <T> ListItem<T> {
    fn append(&mut self, x: T) {
        match *self {
            Node(_, ref mut a@box Cap) => *a = box Node(x, box Cap),
            Node(_, ref mut a@box Node(_, _)) => a.append(x),       // <---
            Cap => {
                let mut n = Node(x, box Cap);
                swap(&mut n, self);
            }
        };
    }
}
impl列表项{
fn追加(&mut self,x:T){
匹配自我{
节点(u,ref muta@boxCap)=>*a=箱节点(x,箱盖),
节点(u,ref muta@box节点(,))=>a.append(x),//{
设mut n=节点(x,箱盖);
交换(&M)n,自交换;
}
};
}
}
这意味着,对于列表中已经存在的每个元素,您将在堆栈上创建一个新的函数框架(除非编译器对其进行优化),对于足够数量的元素,该框架将决定性地溢出堆栈


为了避免溢出,您可以切换到迭代版本(带有循环)。

不幸的是,Rust不能做到这一点,这意味着您不能依赖递归进行迭代繁重的操作

据报道,他们似乎不太可能在未来增加这一功能


恐怕您必须将代码转换为常规循环。

不幸的是,Rust不能做到这一点,这意味着您不能依赖递归进行迭代繁重的操作

据报道,他们似乎不太可能在未来增加这一功能

恐怕您必须将代码转换为常规循环