Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Enums 匹配枚举时无法移出借用的内容_Enums_Rust - Fatal编程技术网

Enums 匹配枚举时无法移出借用的内容

Enums 匹配枚举时无法移出借用的内容,enums,rust,Enums,Rust,我正在尝试打印一棵树(它现在是一个LinkedList,但会被修复): 我只读取值,不改变任何东西。我将一个值从一个引用分配给另一个值,尝试取消引用一个Rc值,并将其存储在一个本地mut变量中 也许像这样的事情可以奏效: while true { println!("{}", current.value); match &current.kind { &NodeKind::Branch(next) => { curre

我正在尝试打印一棵树(它现在是一个
LinkedList
,但会被修复):

我只读取值,不改变任何东西。我将一个值从一个引用分配给另一个值,尝试取消引用一个
Rc
值,并将其存储在一个本地
mut
变量中

也许像这样的事情可以奏效:

while true {
    println!("{}", current.value);
    match &current.kind {
        &NodeKind::Branch(next) => {
            current = next;
        }
        &NodeKind::Leaf => {
            break;
        }
    }
}
或许

let mut current = &Rc::new(root);
while true {
    println!("{}", current.value);
    match current.kind {
        NodeKind::Branch(next) => {
            current = &next;
        }
        NodeKind::Leaf => {
            break;
        }
    }
}

但是我也遇到了同样的错误,加上“下一步”的寿命不够长,我还不能解决1)的问题,但我确实找到了2)的答案

在顶部,您需要使用:

使用std::rc::rc

而不是


使用std::rc

显示错误是因为默认情况下,
match
将执行移动

移动一个值后(即不是由引用获取的,或者调用了采用
self
的方法)后续调用失败。您可能需要克隆,这是
struct
enum
所缺少的属性。一旦添加这些(
#[派生(克隆)
)并将
当前=*下一步;
更改为
当前=(*下一步).Clone();
,您的程序将再次工作

use std::io;
use std::rc::Rc;

#[derive(Clone)]
enum NodeKind {
    Branch(Rc<Node>),
    Leaf,
}

#[derive(Clone)]
struct Node {
    value: i32,
    kind: NodeKind,
}

fn main() {
    let leaf = Node { value: 10, kind: NodeKind::Leaf };
    let branch = Node { value: 50, kind: NodeKind::Branch(std::rc::Rc::new(leaf)) };
    let root = Node { value: 100, kind: NodeKind::Branch(std::rc::Rc::new(branch)) };

    let mut current = root;
    while true {
        println!("{}", current.value);
        match current.kind {
            NodeKind::Branch(next) => {
                current = (*next).clone();
            }
            NodeKind::Leaf => {
                break;
            }
        }
    }

    let reader = io::stdin();
    let buff = &mut String::new();
    let read = reader.read_line(buff);
}
使用std::io;
使用std::rc::rc;
#[衍生(克隆)]
枚举节点索引{
分行(Rc),
叶子,
}
#[衍生(克隆)]
结构节点{
值:i32,
种类:NodeKind,
}
fn main(){
让leaf=Node{value:10,kind:NodeKind::leaf};
让branch=Node{value:50,kind:NodeKind::branch(std::rc::rc::new(leaf))};
让root=Node{value:100,kind:NodeKind::Branch(std::rc::rc::new(Branch))};
让mut current=root;
虽然是真的{
println!(“{}”,current.value);
匹配当前类型{
NodeKind::分支(下一步)=>{
当前=(*下一个).clone();
}
NodeKind::Leaf=>{
打破
}
}
}
让reader=io::stdin();
让buff=&mut字符串::new();
让read=reader.read\u行(buff);
}


如果你
让mut current=&root
那么你可以避免
克隆()
,根据弗拉基米尔下面的回答()。

这里不需要克隆,完全可以通过引用实现你想要的:

use std::rc::Rc;

enum NodeKind {
    Branch(Rc<Node>),
    Leaf,
}

struct Node {
    value: i32,
    kind: NodeKind,
}

fn main() {
    let leaf = Node { value: 10, kind: NodeKind::Leaf };
    let branch = Node { value: 50, kind: NodeKind::Branch(Rc::new(leaf)) };
    let root = Node { value: 100, kind: NodeKind::Branch(Rc::new(branch)) };

    let mut current = &root;
    loop {
        println!("{}", current.value);
        match current.kind {
            NodeKind::Branch(ref next) => {
                current = &**next;
            }
            NodeKind::Leaf => break,
        }
    }
}
使用std::rc::rc;
枚举节点索引{
分行(Rc),
叶子,
}
结构节点{
值:i32,
种类:NodeKind,
}
fn main(){
让leaf=Node{value:10,kind:NodeKind::leaf};
让branch=Node{value:50,kind:NodeKind::branch(Rc::new(leaf))};
让root=Node{value:100,kind:NodeKind::Branch(Rc::new(Branch))};
让mut current=&root;
环路{
println!(“{}”,current.value);
匹配当前类型{
NodeKind::Branch(ref next)=>{
当前=&**下一步;
}
NodeKind::Leaf=>break,
}
}
}
代码中唯一重要的更改是匹配中的模式为
ref next
current
类型为
&Node

ref
模式通过引用绑定它们的变量,也就是说,
next
具有类型
&Rc
。要从中获取
&Node
,您需要将其取消引用两次以获取
Node
,然后再次引用以获取
&Node
。由于Deref强制,还可以写入
current=&next
,编译器将自动为您插入适当数量的
*
s

我还将
while(true)
更改为
loop
,因为它更惯用,并且有助于编译器对代码进行推理


所有树状结构的遍历在Rust中都是这样完成的。
ref
模式允许不移出变量,这在您只需要读取数据时是绝对必要的。您可以找到更多关于模式以及它们如何与所有权和借用交互的信息。

当然可以在
match
子句中借用,但在您的c如果您受到结构创建方式的限制。即使您借用了,您仍然需要通过
clone
显式克隆它,或者通过
Copy
隐式克隆它。您似乎在寻找遍历树的迭代器。也许我应该编写
let mut current=Rc::new(root)
,所以我只想复制Rc和i32,但不想复制整个结构。我只想读取Rc地址,取消引用,复制i32并打印它,然后读取下一个节点的地址,并将当前地址分配给此地址,直到遇到叶节点。只有Rc和i32的复制(这在标准库和Rc中实现).我明白了,所以电流不需要是一个具体的值,而是一个参考值。这改变了一切。
use std::rc::Rc;

enum NodeKind {
    Branch(Rc<Node>),
    Leaf,
}

struct Node {
    value: i32,
    kind: NodeKind,
}

fn main() {
    let leaf = Node { value: 10, kind: NodeKind::Leaf };
    let branch = Node { value: 50, kind: NodeKind::Branch(Rc::new(leaf)) };
    let root = Node { value: 100, kind: NodeKind::Branch(Rc::new(branch)) };

    let mut current = &root;
    loop {
        println!("{}", current.value);
        match current.kind {
            NodeKind::Branch(ref next) => {
                current = &**next;
            }
            NodeKind::Leaf => break,
        }
    }
}