Skip to content

move 与 destroy ​

move:交出所有权 ​

yidong(移动 / move)把一个变量的值直接交给别人,不复制。交出去之后,原变量就不能再用了:

cpro
bl a = "hello"
bl b = yidong a     // a 的内容直接交给 b,没有复制
dayin(b)            // hello
dayin(a)            // ✗ a 已经被移走
cpro
变量 a = "hello"
变量 b = 移动 a     // a 的内容直接交给 b,没有复制
打印(b)             // hello
打印(a)             // ✗ a 已经被移走
cpro
var a = "hello"
var b = move a      // a 的内容直接交给 b,没有复制
print(b)            // hello
print(a)            // ✗ a 已经被移走

确定原变量之后不再需要时,用 yidong 省掉一次复制。不写也完全正确,只是多复制一次。

能写在哪里 ​

cpro
bl b = yidong a     // 初始化
b = yidong a        // 赋值
fanhui yidong a     // 返回
f(yidong a)         // 传参
cpro
变量 b = 移动 a     // 初始化
b = 移动 a          // 赋值
返回 移动 a         // 返回
f(移动 a)           // 传参
cpro
var b = move a      // 初始化
b = move a          // 赋值
return move a       // 返回
f(move a)           // 传参

规则 ​

重新赋值可以让原变量恢复使用:

cpro
bl a = "hi"
bl b = yidong a
a = "new"
dayin(a)            // ✓ new
cpro
变量 a = "hi"
变量 b = 移动 a
a = "new"
打印(a)             // ✓ new
cpro
var a = "hi"
var b = move a
a = "new"
print(a)            // ✓ new

不能重复移动同一个变量:

cpro
bl a = "hi"
bl b = yidong a
bl c = yidong a     // ✗ a 已经被移走
cpro
变量 a = "hi"
变量 b = 移动 a
变量 c = 移动 a     // ✗ a 已经被移走
cpro
var a = "hi"
var b = move a
var c = move a      // ✗ a 已经被移走

只能移动局部变量,结构体字段、数组元素、全局变量都不行:

cpro
bl x = yidong a         // ✓ 局部变量
bl y = yidong a.name    // ✗
bl z = yidong arr[0]    // ✗
cpro
变量 x = 移动 a         // ✓ 局部变量
变量 y = 移动 a.name    // ✗
变量 z = 移动 arr[0]    // ✗
cpro
var x = move a          // ✓ 局部变量
var y = move a.name     // ✗
var z = move arr[0]     // ✗

提前释放 ​

变量离开作用域时会自动释放。如果作用域还很长、但某个大的值已经用不到了,可以用 xiaohui(销毁 / destroy)提前释放它:

cpro
hs load_text() zifuchuan {
    fanhui "很长的文本……"
}

rukou() {
    bl raw leixing zifuchuan = load_text()
    bl n leixing z64 = raw.changdu()
    xiaohui raw         // 后面用不到了,先释放
    dayin(n)
}
cpro
函数 load_text() string {
    返回 "很长的文本……"
}

入口() {
    变量 raw 类型 string = load_text()
    变量 n 类型 i64 = raw.length()
    销毁 raw            // 后面用不到了,先释放
    打印(n)
}
cpro
fn load_text() string {
    return "很长的文本……"
}

rukou() {
    var raw type string = load_text()
    var n type i64 = raw.length()
    destroy raw         // 后面用不到了,先释放
    print(n)
}

释放之后变量就不能再用了,重新赋值可以恢复:

cpro
bl s leixing zifuchuan = "hi"
xiaohui s
dayin(s)            // ✗ s 已经被销毁
s = "world"         // ✓ 重新赋值后恢复
dayin(s)
cpro
变量 s 类型 string = "hi"
销毁 s
打印(s)             // ✗ s 已经被销毁
s = "world"         // ✓ 重新赋值后恢复
打印(s)
cpro
var s type string = "hi"
destroy s
print(s)            // ✗ s 已经被销毁
s = "world"         // ✓ 重新赋值后恢复
print(s)

能销毁什么 ​

可以不可以
字符串、动态数组、闭包数字、zhenjia(bool)、zifu(rune)等简单类型——本来就不占额外内存
含字符串或数组字段的结构体借用参数——值是别人的
内部是上述类型的 optional全局变量、只读变量
结构体字段、数组元素——只能销毁整个变量
nocopy 结构体——用它自己的关闭函数

move 和 destroy 的区别 ​

yidongxiaohui
值的去向交给接收方直接释放
写法表达式,要有接收方单独一条语句
之后原变量不能再用,重新赋值可恢复同左

cpro 目前处于测试阶段