可变性

日子长到一天接一天,他们丧失了各自的名称。对于我来说,唯一还有点意义的词是“昨天”和“明天”。 ——《局外人》

Rust与其他语言与众不同的一点就是“不可变性”,对于大部分变量来说,可变性都不是他们的默认状态。但是对于一门编程语言来说,可变性又是必需的,所以Rust对此引入了mut关键词来修饰变量来使得变量是可变的——当一个绑定是可变的,这意味着你可以改变它指向的内容。先看一个小例子:

let mut num:i32 = 0;
let mut x:i32 = 9;
let borrow = &mut x;//等同于let borrow:&mut i32 = &mut x;
*borrow = 10;//位置2
borrow = &mut num;//位置1 error cannot assign to a immutable variable

这个例子定义了一个可变的32位长整数x,一个不可变绑定的引用——它指向一个可变的32位长整数。这意味着borrow不能够绑定到另外一个变量,如位置1所示。但是由于引用指向的是一个可变的数据,所以我们可以改变其指向的数据的值,就像位置2处的操作一样。
再看一个例子:

fn main(){
    let mut num2:i32 = 3;
    let mut num:i32 = 9;
    {
        let mut immutable_borrow:&mut i32 = &mut num;
        *immutable_borrow = 10;
        immutable_borrow = &mut num2;
        println!("{}", *immutable_borrow);//3
    }
    println!("{}", num);//10
}

结构体字段级别可变性

可变性是借用或者绑定的属性之一,这意味着,在某些情况下我们不能够如愿所偿的使用mut关键字来修饰变量使得其可变。举个例子:在结构体之中,我们就不能够对一个普通数据类型的字段设置其为可变。如下所示:

struct Foo{
  //error: expected identifier, found keyword `mut`
  mut a: i32
}

所以说你不能够在结构体中的普通数据类型的字段设置mut。但是呢尽管不能够设置,但是仍旧可以改变字段的值.....看下面这个例子:

fn main(){
  let mut foo1:Foo = Foo{a: 8};
  foo1.a = 9;
  println!("{}", foo1.a);
  let foo2:Foo = Foo{a: 1};
  //foo2.a = 3; error: cannot assign to immutable field `foo2.a`
  //println!("{}", foo2.a);
}
struct Foo{
  a: i32
}
impl Foo{
  fn get_a(&self) -> i32{self.a}
}

上面很奇怪,要知道我们Foo结构体中的字段a是不可变的,尽管foo1是可变绑定,但是为什么可以改变foo1的a属性的值呢?这难道不是两回事吗?目前为止并不明白,不过为了达到字段级别可变性这一目的,还是有其它方法的:

use std::cell::Cell;
fn main(){
  let foo:Foo = Foo{a: Cell::new(9)};
  foo.a.set(99);
  println!("foo.a {:?}", foo.a);//foo.a Cell { value: 99 }
}
struct Foo{
  a: Cell
}

END

你可能感兴趣的:(可变性)