【问题标题】:Why mutable reference on `const` is not an error?为什么`const`上的可变引用不是错误?
【发布时间】:2021-03-10 13:47:48
【问题描述】:

由于Rust book v1.30 明确表示:

... Rust 中的常量在内存中没有固定地址。这是因为它们有效地内联到使用它们的每个地方。因此,对相同常量的引用不一定保证引用相同的内存地址。

为什么编译器允许在const 变量上获得可变引用。它只是说的是警告/注释而不是错误。

warning: taking a mutable reference to a `const` item
 --> src/main.rs:5:22
  |
6 |     println!("{:p}", &mut VALUE);
  |                      ^^^^^^^^^^
  |
  = note: `#[warn(const_item_mutation)]` on by default
  = note: each usage of a `const` item creates a new temporary
  = note: the mutable reference will refer to this temporary, not the original `const` item

为了测试这一点,一个简单的代码示例:

fn main() {
    const VALUE: u64 = 0;
    println!("{:p}", &VALUE);      // 0x10622ed78 // same
    println!("{:p}", &VALUE);      // 0x10622ed78
    println!("{:p}", &mut VALUE);  // 0x7ffee9a08890 // different
    println!("{:p}", &mut VALUE);  // 0x7ffee9a088e8
}

Rust playground

正如预期的那样,const 的内存位置可能会改变(特别是在使用可变引用访问时)。

【问题讨论】:

  • 我认为警告很清楚发生了什么。您没有得到对const 变量的可变引用,const 变量的内存位置也没有改变。您正在做的是创建许多不同的临时对象,它们是从VALUE 复制的,并且这些临时对象的地址不同。如果您将VALUE 替换为(1+2) 之类的东西,也会发生同样的事情,println!("{:p}", &mut (1+2)); 也是如此
  • 如果你认为像&mut 1 这样的东西是完全允许的(有时非常有用!),没有充分的理由不允许&mut FOO 其中FOO 是,比如说,1。但是事实证明,大多数&mut FOO 实际上都是错误的,这就是引入警告的原因。

标签: rust


【解决方案1】:

在某些情况下,它的行为是可预测的。特别是,如果您重复使用相同的参考:

const VALUE: u64 = 0;

fn main() {
    let v = &mut VALUE;
    add_1(v);
    add_1(v);
    assert_eq!(*v, 2);
}

fn add_1(v: &mut u64) {
    *v += 1;
}

与首先添加本地绑定相比,我无法立即想到这样做的好处。但它不会导致内存不安全,所以不用担心。

鉴于这不是 Rust 1.0 版中的错误,Rust 开发人员以后不能让它成为错误,因为这会破坏向后兼容性。

【讨论】:

    【解决方案2】:

    对常量进行可变引用会创建一个新的临时变量。编译器会将您的代码视为:

    fn main() {
        const VALUE : u64 = 0;
        println!("{:p}", &VALUE);      // 0x10622ed78 // same
        println!("{:p}", &VALUE);      // 0x10622ed78
        let mut tmp1 = VALUE;
        println!("{:p}", &mut tmp1);  // 0x7ffee9a08890 // different
        let mut tmp2 = VALUE;
        println!("{:p}", &mut tmp2);  // 0x7ffee9a088e8
    }
    

    Try in playground

    这似乎是一种奇怪的做事方式,当常量为 function pointershave interior mutability 时,这种行为有合理的用例。

    【讨论】:

      猜你喜欢
      • 2016-10-28
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-10
      • 2018-10-24
      • 1970-01-01
      • 2011-07-15
      相关资源
      最近更新 更多