可变性

作者: BIGHAI | 来源:发表于2017-06-16 11:27 被阅读0次

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

    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<i32>
    }
    

    END

    相关文章

      网友评论

          本文标题:可变性

          本文链接:https://www.haomeiwen.com/subject/pdppqxtx.html