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