Rust模式匹配中|引发‘值被移动后使用’报错?实为IDE误报
Rust中match分支竖线
|操作符的语义困惑 编辑:本问题基于错误前提。实际是我的IDE产生了假阳性提示;代码完全合法。详见下方回答。
在Rust中,我对match分支里的竖线|操作符的语义有些困惑。具体来说,我编写的代码中使用竖线似乎会导致借用检查器抛出“值被移动后使用”的错误。
以下是最小复现示例:第一个函数doesnt_work会通不过借用检查,而第二个在我看来逻辑等价的函数works却能正常运行。
fn doesnt_work(token_stream: &mut impl Iterator<Item = Token>) { for token in token_stream { match token { Token::ImplicitNode(data) | Token::ExplicitNode(data) => _buildnode(data), _ => (), } } } fn works(token_stream: &mut impl Iterator<Item = Token>) { for token in token_stream { match token { Token::ImplicitNode(data) => _buildnode(data), Token::ExplicitNode(data) => _buildnode(data), _ => (), } } } #[derive(Debug, Eq, PartialEq, Clone)] struct NodeData {} #[derive(Debug, Eq, PartialEq, Clone)] enum Token { ImplicitNode(NodeData), ExplicitNode(NodeData), OtherVariantsThatWeArentInterestedIn, } fn _buildnode(data: NodeData) { unimplemented!() }
需要说明的是,我不是询问如何修复这个问题;我想理解为什么借用检查器会对doesnt_work的实现报错。
我原本以为竖线操作符本质上是多个相同match分支的简写,但显然并非如此。那么,正确的理解方式应该是什么?
解答
首先明确:你写的doesnt_work代码本身是完全合法的Rust代码,报错只是IDE的假阳性提示。
关于match分支中|的语义,正确理解是:当在同一个分支用|匹配多个变体并绑定同名变量时,Rust会确保这些绑定的类型完全一致,且只会执行一次移动——因为匹配时只会命中其中一个变体,变量data只会被绑定一次,不存在重复移动的问题。
你看到错误提示,是因为部分IDE的静态分析工具(比如旧版本的rust-analyzer)处理这种模式时存在误判,误以为同一个变量被多次绑定导致重复移动,但实际上Rust编译器完全认可这种写法,编译时不会报错。
简单说,|在这里确实是多个匹配分支的简写,逻辑上和分开写两个分支完全等价,你的理解并没有错,问题出在IDE的假阳性提示上。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

