Rust 中赋值的语义是什么? [英] What's the semantic of assignment in Rust?

查看:46
本文介绍了Rust 中赋值的语义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How could know the type of a binding if I use auto type deduction when creating a binding? what if the expression on the right side is a borrow(like let x = &5;), will it be value or a borrow? What will happen if I re-assign a borrow or a value?

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

Just for check, I do can re-assign a borrow if I use let mut x: &mut T = &mut T{}; or let mut x:&T = & T{};, right?

推荐答案

我觉得 bindingassigning 之间有些混淆:

I sense some confusion between binding and assigning:

  • 绑定引入了一个新变量,并将其与一个值相关联,
  • 赋值会用另一个值覆盖一个值.
  • Binding introduces a new variable, and associates it to a value,
  • Assigning overwrites a value with another.

这可以用简单的两行来说明:

This can be illustrated in two simple lines:

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

<小时>

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


A binding may appear in multiple places in Rust:

  • let 语句,
  • if let/while let 条件,
  • match 表达式中的案例,
  • 甚至在 for 表达式中,在 in 的左侧.
  • let statements,
  • if let/while let conditions,
  • cases in a match expression,
  • and even in a for expression, on the left side of in.

只要有绑定,Rust 的语法也允许模式匹配:

Whenever there is a binding, Rust's grammar also allows pattern matching:

  • let 语句和 for 表达式的情况下,模式必须是无可辩驳的,
  • if letwhile letmatch的情况下,模式可能无法匹配.
  • in the case of let statements and for expressions, the patterns must be irrefutable,
  • in the case of if let, while let and match cases, the patterns may fail to match.

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

Pattern matching means that the type of the variable introduced by the binding differs based on how the binding is made:

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

<小时>

赋值总是需要使用赋值运算符=.


Assigning always requires using =, the assignment operator.

赋值时,前一个值被覆盖,如果实现了Drop,则对其调用drop.

When assigning, the former value is overwritten, and drop is called on it if it implements 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,或引用.

The value that is overwritten may be as simple as an integer or float, a more involved struct or enum, or a reference.

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

覆盖引用不会覆盖引用指向的值,而是覆盖引用本身.原始值仍然存在,准备好后将被删除.

Overwriting a reference does not overwrite the value pointed to by the reference, but the reference itself. The original value still lives on, and will be dropped when it's ready.

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

To overwrite the pointed to value, one needs to use *, the dereference operator:

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

如果解引用值的类型需要它,drop 将被调用:

If the type of the dereferenced value requires it, drop will be called:

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

我邀请你去游乐场玩玩,你可以开始从这里:

I invite you to use to playground to and toy around, you can start from here:

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

<小时>

希望现在事情应该更清楚了,所以让我们检查一下您的样本.


Hopefully, things should be a little clearer now, so let's check your samples.

let x = &5;

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

x is a reference to i32 (&i32). What happens is that the compiler will introduce a temporary in which 5 is stored, and then borrow this temporary.

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

不可能.T{} 的类型是 T 而不是 &mut T,所以编译失败.您可以将其更改为 let mut x: &mut T = &mut T{};.

Is impossible. The type of T{} is T not &mut T, so this fails to compile. You could change it to let mut x: &mut T = &mut T{};.

你的最后一个例子是相似的.

And your last example is similar.

这篇关于Rust 中赋值的语义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆