【问题标题】:What's the difference between immutable and mutable references to an i32 when adding?添加时对 i32 的不可变引用和可变引用有什么区别?
【发布时间】:2017-01-22 18:14:03
【问题描述】:

我有

fn plus_one(x: &i32) -> i32 {
    x + 1
}

fn plus_one_star(x: &i32) -> i32 {
    *x + 1
}

fn plus_one_mut(x: &mut i32) -> i32 {
    x + 1
}

fn plus_one_mut_star(x: &mut i32) -> i32 {
    *x + 1
}

fn main() {
    let a: i32 = 5;
    let mut b: i32 = 5;

    println!("{:?}", plus_one(&a));
    println!("{:?}", plus_one_star(&a));
    println!("{:?}", plus_one_mut(&mut b));
    println!("{:?}", plus_one_mut_star(&mut b));
    // I expect all to print '6' as I never actually mutate b
}

第三个函数plus_one_mut 编译失败:error[E0369]: binary operation `+` cannot be applied to type '&mut i32'

为什么这个带有可变引用的函数编译失败?

【问题讨论】:

    标签: rust mutable


    【解决方案1】:

    正如错误消息所说:

    二元运算+不能应用于类型'&mut i32'

    那是因为它没有实现。查看the documentation for i32,您将看到Add 的这些实现:

    • impl Add<i32> for i32
    • impl<'a> Add<i32> for &'a i32
    • impl<'a> Add<&'a i32> for i32
    • impl<'a, 'b> Add<&'a i32> for &'b i32

    您需要取消对&mut i32 的引用才能访问i32,它确实有一个Add 实现。

    为什么它没有那个实现?我不确定。也许您可以向 Rust 提交 PR 以添加它……就我个人而言,我不记得曾经需要它。通常,如果您有 &mut T,那是因为您想要更新它,所以您应该有 *foo += 1 之类的东西。

    【讨论】:

    • 奇怪的是x.add(1) 在所有情况下都有效...在那种情况下可能会出现强制?
    • @PaoloFalabella 我不确定什么时候 coercion 是正确的术语;但是是的,我认为automatic dereferencing 正在发挥作用。
    • 所以在这种情况下&T 的行为就像T。一般来说,我应该在使用它们之前取消引用我所有的不可变引用吗?还是为&T 实现大部分Ts 方法非常普遍?
    • @turbulencetoo 我不确定我是否关注你。如果你有一个值,你可以调用那种类型的 methods 来接受 &selfself 而无需任何仪式。无论您是否将方法实现为采用self&self,归结为函数需要做什么。我敢打赌,大多数方法都采用&self,因为它们不需要&mut selfself 授予的权力。我发现必须添加显式 * 并且通常等到编译器告诉我添加它是相当罕见的。
    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 2011-06-01
    • 1970-01-01
    相关资源
    最近更新 更多