Rust中匹配Rc包裹的递归定义Enum时为何需要在match中添加&符号
问题原因解释
基础规则:Rc<T>不允许转移内部值的所有权
Rc<T>是共享所有权的智能指针,Rust的设计规则禁止通过解引用Rc<T>直接获取内部T的所有权:如果允许把内部值挪走,其他指向同一块内存的Rc指针就会访问无效数据,引发内存安全问题。
你直接写match *list的时候,本质是尝试把Rc包裹的Node值整体移出,匹配到Node::Cons(value, _next)分支时,类型为Rc<Node>的_next字段没有实现Copy trait,需要发生所有权转移,这就触发了编译器的E0507报错。
而加&之后你匹配的是&Node类型的不可变引用,所有分支绑定的value、_next都是借用,不会触及Rc内部值的所有权,自然可以正常编译。
两个特例的原理
1. 去掉递归定义仅保留i32字段可正常编译
因为i32是实现了Copy trait的基础类型,当你的Node枚举所有字段都是Copy类型时,解引用Rc匹配的过程中会直接复制字段的值,不需要转移Rc内部数据的所有权,因此不会触发移动规则的限制。
2. 把Rc替换为Box可正常编译
Box<T>是独占所有权的智能指针,它实现了DerefMove trait,允许通过解引用直接拿走内部T的所有权——毕竟Box的所有者是唯一的,你把内部值挪走之后,Box本身会被销毁,不存在其他指针访问同一块内存的风险,符合Rust的安全规则。
内容的提问来源于stack exchange,提问作者Erben Mo
相关产品推荐
相关产品推荐

