什么是Rust中赋值的语义?

时间:2017-12-05 08:19:41

标签: rust

如果在创建绑定时使用自动类型推导,怎么知道绑定的类型?如果右侧的表达式是借用(如let x = &5;),它会是值还是借用呢?如果我重新分配借款或价值会怎样?

只是为了检查,如果我使用let mut x: &mut T = &mut T{};let mut x:&T = & T{};,我可以重新分配借款吗?

1 个答案:

答案 0 :(得分:5)

我感觉绑定分配之间存在一些混淆:

  • 绑定引入了一个新变量,并将其与值
  • 相关联
  • 分配会覆盖另一个值。

这可以用两个简单的方式来说明:

let mut x = 5;    //  Binding
x = 10;           //  Assigning

绑定可能会出现在Rust的多个位置:

  • let陈述,
  • if let / while let条件,
  • match表达式中的案例
  • 甚至在for表达式的in左侧。

每当有绑定时,Rust的语法也允许模式匹配

  • let语句和for表达式的情况下,模式必须是无可辩驳的,
  • 如果是if letwhile letmatch,则模式可能无法匹配。

模式匹配意味着绑定引入的变量类型根据绑定的方式而不同:

let x = &5;    //  x: &i32
let &y = &5;   //  y: i32

分配始终需要使用=,即赋值运算符。

分配时,前一个值会被覆盖,如果它实现drop,则会调用Drop

let mut x = 5;
x = 6;
//  Now x == 6, drop was not called because it's a i32.

let mut s = String::from("Hello, World!");
s = String::from("Hello, 神秘德里克!");
//  Now s == "Hello, 神秘德里克!", drop was called because it's a String.

被覆盖的值可能像整数或浮点数一样简单,涉及的内容更structenum,或引用

let mut r = &5;
r = &6;
//  Now r points to 6, drop was not called as it's a reference.

覆盖引用不会覆盖引用指向的值,而是覆盖引用本身。原始值仍然存在,并且在准备就绪时将被删除。

要覆盖指向的值,需要使用解除引用运算符*

let mut x = 5;
let r = &mut x;
*r = 6;
//  r still points to x, and now x = 6.

如果解除引用值的类型需要它,则会调用drop

let mut s = String::from("Hello, World!");
let r = &mut s;
*r = String::from("Hello, 神秘德里克!");
//  r still points to s, and now s = "Hello, 神秘德里克!".

我邀请你到游乐场和玩具周围,你可以start from here

fn main() {
    let mut s = String::from("Hello, World!");
    {
        let r = &mut s;
        *r = String::from("Hello, 神秘德里克!");
    }
    println!("{}", s);
}

希望现在的事情应该更加清晰,所以让我们检查你的样品。

let x = &5;

x是对i32(&i32)的引用。发生的事情是编译器将引入一个存储5的临时值,然后借用它。

let mut x: &mut T = T{};

不可能。 T{}的类型为T而非&mut T,因此无法编译。您可以将其更改为let mut x: &mut T = &mut T{};

你的最后一个例子是类似的。