You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中为何vec_loop需显式解引用,而vec_map无需?

Rustlings vecs2.rs:为何vec_loop需显式解引用而vec_map不用?

问题代码与错误

编写的代码

fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for element in v.iter_mut() {
        // TODO: 将Vec中每个元素乘以2
        element =  element * 2; // 此处报错!
    }
    // 最终v应为[4, 8, 12, 16, 20]
    v
}

fn vec_map(v: &Vec<i32>) -> Vec<i32> {
    v.iter().map(|element| {
        // TODO: 同样将每个元素乘以2,但不修改原Vec
        element * 2 // 无报错
    }).collect()
}

报错信息

error[E0369]: cannot multiply `&mut i32` by `{integer}`
  --> exercises/vecs/vecs2.rs:16:28
   |
16 |         element =  element * 2; // error here!!!
   |                    ------- ^ - {integer}
   |                    |
   |                    &mut i32
   |
help: `*` can be used on `i32` if you dereference the left-hand side
   |
16 |         element =  *element * 2; // error here!!!
   |                    +

核心疑问

为什么vec_loop里必须显式写*element才能运算,而vec_map里直接用element *2就可以?

原因解析

1. vec_map中的隐式解引用:运算符重载的语法糖

v.iter()返回只读迭代器Iter<i32>,迭代出的element是&i32类型(对原元素的不可变引用)。

Rust标准库为**不可变引用&T**实现了Mul(乘法)运算符重载——当T本身支持乘法时,&T可以直接和对应类型做运算,编译器会自动完成解引用操作,相当于把element *2转换成(*element) *2。这是Rust为简化代码提供的语法糖,因此不需要手动写*。

2. vec_loop中的显式解引用:两个必须的理由

v.iter_mut()返回可变迭代器IterMut<i32>,迭代出的element是&mut i32类型(对原元素的可变引用):

  • 运算层面:标准库没有为**可变引用&mut i32**实现和整数的乘法重载,直接写element *2会报错,必须显式解引用成i32类型才能和整数相乘。
  • 赋值层面:你要修改的是引用指向的内存中的值,而非引用变量本身。element是&mut i32类型的变量,若写element = ...,是试图把i32值赋值给引用变量,类型完全不匹配。正确做法是通过*element访问目标内存,再给它赋值:*element = *element *2。

修正后的vec_loop代码

fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for element in v.iter_mut() {
        *element = *element * 2;
    }
    v
}

总结

  • vec_map里的隐式解引用是运算符重载带来的语法糖,仅针对不可变引用的运算场景;
  • vec_loop里需要显式解引用,一是因为可变引用没有对应的乘法重载,二是因为要修改引用指向的内存值,必须通过解引用来访问目标地址。

内容的提问来源于stack exchange,提问作者Archsx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:55:11