Rust中为何对已为引用的元素在for循环中用&item?
关于Rust中Slice章节代码的模式匹配疑问解答
先明确核心:你看到的&item是模式匹配的解构语法,不是普通的变量引用声明,这是Rust模式匹配的特性,我们一步步拆解:
1. 原代码中迭代器的返回值分析
先看这段代码的迭代逻辑:
let bytes = s.as_bytes(); // 得到 &[u8] 类型的字节切片引用 for (i, &item) in bytes.iter().enumerate() { // ... }
bytes.iter():对&[u8]调用iter(),会返回一个迭代器,每次迭代产出的是切片中每个字节的引用,也就是&u8类型。.enumerate():把迭代器的每个元素和它的索引打包成元组,所以最终迭代产生的每个元素是(usize, &u8)类型(第一个元素是索引,第二个是字节的引用)。
2. 循环中的&item是解构匹配
循环里的(i, &item)是在对(usize, &u8)这个元组做模式匹配:
i直接绑定元组的第一个元素(索引,usize类型)。&item是匹配元组的第二个元素(&u8):这里的&是模式的一部分,作用是解构这个引用——把引用指向的u8值绑定到item变量上。这样item的类型就是u8,能直接和b' '(u8类型的空格字节)做比较。
如果去掉&,item就会直接绑定&u8类型的引用,这时候要比较的话必须手动解引用:
for (i, item) in bytes.iter().enumerate() { if *item == b' ' { // 这里需要用*解引用 return i; } }
3. 你模拟代码报错的原因
你写的这段代码:
let some_string = String::from("hello"); let &some_var = &some_string;
为什么报错?
&some_string是&String类型,模式&some_var试图解构这个引用,意味着Rust会尝试把&String内部的String所有权转移给some_var。但String没有实现Copytrait,Rust不允许从引用中直接取出所有权(这会破坏借用规则:原some_string的所有权会被夺走,但它本身还存在)。
如果想要some_var拥有String的所有权,应该用克隆:
let some_var = some_string.clone();
如果只是想要引用,直接绑定即可:
let some_var = &some_string;
内容的提问来源于stack exchange,提问作者bython
相关产品推荐
相关产品推荐

