Rust 借用循环和 Vec

问题描述 投票:0回答:2

我只是尝试构建一种树:有一个根节点,然后想将节点作为子节点添加到根节点。它遇到了这个错误,我无法理解出了什么问题。

#[derive(Clone)]
pub struct Node {
    id: String,
    file: FileContent, 
    nodes: Vec<Node>,
}

impl Node {
    pub fn new(file:FileContent) -> Self {
        Self {
            id: file.path.clone(),
            file: file.clone(),
            nodes:Vec::<Node>::new(),
        }
    }

    pub fn add(mut self, node: Node) -> Self{
        self.nodes.push(node.clone());
        self
    }
}

#[derive(Clone)]
pub struct FileContent {
    path: String,
    length: usize,
    content_type: String,
}

pub fn create_test_file_content() -> Vec<FileContent> {
    let mut file_content = Vec::<FileContent>::new();
    file_content.push(FileContent {path:String::from("r/a1/a2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content.push(FileContent {path:String::from("r/b1/ba2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content.push(FileContent {path:String::from("r/b1/bb2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content
}

fn main() {

    let filecontent = create_test_file_content();
    
    let root = Node::new(FileContent {path:String::from("root"),length: 1,content_type: String::from("DIRECTORY")});

    for fc in filecontent {
        let node = Node::new(fc);
        root.add(node);
    }

}

当我遵循克隆根节点的建议时,它就可以工作,但我为什么要这样做呢? “root”仍然在相同的范围内,只有结构成员“nodes”发生了变化。

非常感谢

rust borrow-checker
2个回答
0
投票
 pub fn add(&mut self, node: Node) {
        self.nodes.push(node);
 }

您可能想借用 self 作为可变引用并直接推送节点。我不知道你为什么要从

add()
方法返回 self。

let mut root = Node::new(FileContent {path:String::from("root"),length: 1,content_type: String::from("DIRECTORY")});

您还应该将 root 声明为可变的,因为您正在改变它


0
投票

您的

add
签名是错误的。您没有对 self 使用
可变引用
,而是在消耗
self
。这是一个工作版本:

#[derive(Clone)]
pub struct Node {
    id: String,
    file: FileContent, 
    nodes: Vec<Node>,
}

impl Node {
    pub fn new(file:FileContent) -> Self {
        Self {
            id: file.path.clone(),
            file: file.clone(),
            nodes:Vec::<Node>::new(),
        }
    }

    // NOTE: the &mut ref. Also you can't flat out
    // return Self here and I made it a void method
    // but if you really want a fluent interface to
    // chain methods you could return the same reference
    // &mut self.
    pub fn add(&mut self, node: Node) -> () {
        self.nodes.push(node.clone());
    }
}

#[derive(Clone)]
pub struct FileContent {
    path: String,
    length: usize,
    content_type: String,
}

pub fn create_test_file_content() -> Vec<FileContent> {
    let mut file_content = Vec::<FileContent>::new();
    file_content.push(FileContent {path:String::from("r/a1/a2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content.push(FileContent {path:String::from("r/b1/ba2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content.push(FileContent {path:String::from("r/b1/bb2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content
}

fn main() {

    let filecontent = create_test_file_content();
    
    let mut root = Node::new(FileContent {path:String::from("root"),length: 1,content_type: String::from("DIRECTORY")});

    for fc in filecontent {
        let node = Node::new(fc);
        root.add(node);
    }

}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.