介绍
使用let关键字声明的变量只能在代码块{ ... }中有效。
let x = 0;{let y = 1;};x + y // ERROR!// ^ unbound local 'y'
不过{ ... }声明的变量在嵌套{ ... }是可以使用的。
{let x = 0;{let y = x + 1; // valid}}
shadowing
如果给同一个变量多次赋值,那么这个变量只保留最新值。这个操作被称作shadowing。
let x = 0;assert!(x == 0, 42);let x = 1; // x is shadowedassert!(x == 1, 42);
对于一个 resource 如果没有drop属性,在代码块结束的时候是不会自动销毁的。例如下面代码,我们编辑后使用命令move sandbox publish -v。
address 0x1 {module Shadow {struct Coin has store { value: u64 }fun unused_resource() {let x = Coin { value: 0};x.value = 1;x;}}}
控制台将返回:
ability constraint not satisfiedstruct Coin has store { value: u64 }---- To satisfy the constraint, the 'drop' ability would need to be added herelet x = Coin { value: 0};------ The type '0x1::Shadow::Coin' does not have the ability 'drop'x.value = 1;x;^ Cannot ignore values without the 'drop' ability. The value must be used
如果在嵌套代码块中变量 shadowed ,shadowed 的变量只作用于嵌套代码块中。
script {use Std::Debug;fun main() {let x = 0;{let x = 1;Debug::print(&x);};Debug::print(&x);}}// console[debug] 1[debug] 0
move 和 copy 属性
Move 中所有变量都拥有两种属性move和copy。如果没有显性使用,Move 编译器会自动识别。
copy会在变量内部创建一个新的副本,可以多次使用copy关键字复制相同的变量。
let x = 0;let y = copy x + 1;let z = copy x + 2;
move从局部变量中获取(移动)值,而不会产生新副本,一个变量不能多次move。
let x = 1;let y = move x + 1;// ------ Local was moved herelet z = move x + 2; // Error!// ^^^^^^ Invalid usage of local 'x'y + z
Move 的类型系统不允许一个变量在move后继续使用,可以防止局部变量在赋值之前被使用。
