Skip to content

所有权和作用域

在 Move 编程语言中,每个变量都有其所有权和作用域。所有权指的是哪个代码块“拥有”该变量,而作用域指的是该变量在哪些代码块中是有效的。一旦所有者作用域结束,该变量就会被丢弃,这意味着它不再可用。理解所有权和作用域对于编写安全和高效的 Move 代码至关重要。

所有权

在函数作用域中定义的变量归该作用域所有。当函数执行完毕后,其拥有的变量会被丢弃或释放。

例如:

move
module book::ownership;

public fun owner() {
    let a = 1; // a 归 owner 函数所有 
} // a 在此处被丢弃

public fun other() {
    let b = 2; // b 归 other 函数所有
} // b 在此处被丢弃

#[test]
fun test_owner() {
    owner(); 
    other(); 
    // a 和 b 在此处都不可用
}

返回值

如果一个函数返回一个变量,那么该变量的所有权将被转移给函数的调用者。

例如:

move
module book::ownership;

public fun owner(): u8 {
    let a = 1; // a 在此处定义
    a // 作用域结束,a 被返回
}

#[test]
fun test_owner() {
    let a = owner(); // a 在此处可用
} // a 在此处被丢弃

按值传递

当一个变量被传递给另一个函数时,该变量的所有权会被转移到该函数。这个过程被称为**“移动语义”**。

例如:

move
module book::ownership;

public fun owner(): u8 {
    let a = 10; 
    a // a 被返回
}

public fun take_ownership(v: u8) {
    // v 归 take_ownership 函数所有
} // v 在此处被丢弃

#[test]
fun test_owner() {
    let a = owner(); 
    take_ownership(a); // a 在此处不可用
}

块作用域

每个函数都有一个主作用域,也可以通过使用代码块来创建子作用域。在代码块中定义的变量归该代码块所有,当代码块结束时,这些变量会被丢弃。

例如:

move
module book::ownership;

public fun owner() {
    let a = 1; // a 归 owner 函数的作用域所有
    {
        let b = 2; // b 归代码块所有
        {
            let c = 3; // c 归代码块所有
        }; // c 在此处被丢弃
    }; // b 在此处被丢弃
    // a = b; // 错误:b 在此处不可用
    // a = c; // 错误:c 在此处不可用
} // a 在此处被丢弃

但是,如果使用代码块的返回值,则该变量的所有权会被转移给代码块的调用者。

例如:

move
module book::ownership;

public fun owner(): u8 {
    let a = 1; // a 归 owner 函数的作用域所有
    let b = {
        let c = 2; // c 归代码块所有
        c // c 被返回
    }; // c 在此处被丢弃
    a + b // a 和 b 在此处都可用
}

可复制类型

Move 中的某些类型是可复制的,这意味着它们可以在不转移所有权的情况下进行复制。这对于那些体积小、复制成本低的类型很有用,例如整数和布尔值。当可复制类型被传递给函数、从函数返回或被“移动”到一个作用域然后在其原始作用域中被访问时,Move 编译器会自动复制这些类型。

例如,u8 类型是可复制的:

move
module book::ownership;

public fun copy_example(): u8 {
    let a = 10; // a 是可复制的
    let b = a;  // a 被复制到 b
    b           // b 可用,a 仍然可用
}

总结

  • 所有权和作用域是 Move 编程语言中的重要概念。
  • 了解变量的所有权和作用域可以帮助我们编写更安全、更高效的代码。
  • 所有权决定了哪个代码块“拥有”一个变量,而作用域决定了该变量在哪些代码块中是有效的。
  • 当所有者作用域结束时,该变量会被丢弃。
  • 可复制类型可以在不转移所有权的情况下进行复制。