如果在创建绑定时使用自动类型推导,怎么知道绑定的类型?如果右侧的表达式是借用(如let x = &5;
),它会是值还是借用呢?如果我重新分配借款或价值会怎样?
只是为了检查,如果我使用let mut x: &mut T = &mut T{};
或let mut x:&T = & T{};
,我可以重新分配借款吗?
答案 0 :(得分:5)
我感觉绑定和分配之间存在一些混淆:
这可以用两个简单的方式来说明:
let mut x = 5; // Binding
x = 10; // Assigning
绑定可能会出现在Rust的多个位置:
let
陈述,if let
/ while let
条件,match
表达式中的案例for
表达式的in
左侧。每当有绑定时,Rust的语法也允许模式匹配:
let
语句和for
表达式的情况下,模式必须是无可辩驳的,if let
,while let
和match
,则模式可能无法匹配。模式匹配意味着绑定引入的变量类型根据绑定的方式而不同:
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.
被覆盖的值可能像整数或浮点数一样简单,涉及的内容更struct
或enum
,或引用。
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{};
。
你的最后一个例子是类似的。