介绍

Move 有两种引用类型:不可变引用&和可变引用&mut

用法

函数

Move 提供了创建引用和将可变引用转换为不可变引用等函数:

函数 描述
&e 创建不可变引用并指向 e
&mut e 创建可变引用并指向 e
&e.f 创建不可变引用指向 e 对象的 f
&mut e.f 创建可变引用指向 e 对象的 f
freeze(e) 将可变引用 e 转换为不可变引用

举例

  1. ## 一个struct引用
  2. let str = S { f: 10 };
  3. let ref: u64 = &str.f; // works
  4. let str2: &S = &str;
  5. let ref2: u64 = &_str2.f // works
  6. ## 同一个module多个struct引用
  7. struct A { b: B }
  8. struct B { c: u64 }
  9. fun method(a: &A): &u64 {
  10. &a.b.c
  11. }
  12. ## 引用一个引用是不可以的
  13. script {
  14. use Std::Debug;
  15. fun main() {
  16. let a = 5;
  17. let b = a; // works!此时b是一个字面量
  18. Debug::print(&b); // print参数为引用类型
  19. let x = 7;
  20. let y: &u64 = &x; // works!此时y本身就是一个引用
  21. Debug::print(y); // print参数为引用类型
  22. let z: &&u64 = &y; // compile error
  23. }
  24. }

读取和写入

可变引用和不可变引用都可以以生成引用值的副本来读取;只能修改可变引用,比如*x = y表示会丢弃掉原来存储的x,然后更新为v

读取和写入都使用类似于C语言的语法*

函数 描述
*e 读取指向 e 引用的值
*e1 = e2 修改可变引用e1为引用e2
  1. script {
  2. use Std::Debug;
  3. fun main() {
  4. let e = &mut 10;
  5. Debug::print(e);
  6. *e = *e + 10;
  7. Debug::print(e);
  8. }
  9. }
  10. console:
  11. [debug] 10
  12. [debug] 20

freeze

在不可变引用的上下文中可以转变为可变引用:

  1. ## example 1
  2. // 创建不可变引用
  3. let x = 7;
  4. //这样是可以执行的,因为编译器会自动识别并执行freeze指令(将可变引用转变为不可变引用)
  5. let y: &mut u64 = &mut x;
  6. ## exmaple 2
  7. fun immut_return_immut(x: &u64): &u64 { x }
  8. fun mut_return_immut(x: &mut u64): &u64 { x }
  9. fun expression() {
  10. let x = 0;
  11. let y = 0;
  12. immut_return_immut(&x); //不会自动执行freeze指令
  13. immut_return_immut(&mut x); //自动执行freeze指令
  14. mut_return_immut(&mut x); //不会自动执行freeze指令
  15. }
  16. fun assignment() {
  17. let x = 0;
  18. let y = 0;
  19. let imm_ref: u64 = &x;
  20. imm_ref = &x; //不会自动执行freeze指令
  21. imm_ref = &mut y; //自动执行freeze指令
  22. }

注意

引用reference和元组tuples在 Move 中引用一旦被创建,程序中止时必须被销毁掉。
Move 不支持引用存储在struct中,因为引用在 Move 中不能被序列化;而值在 Move 中是必须被序列化的,这样的设计是因为 Move 的持久化全局存储体系。