Move 2024版本迁移
Move 2024提供了新功能,包括方法语法、位置字段和循环标签。
Move 2024版本迁移引入了一些变化,使得编写Move更加容易,希望也更容易阅读。源语言中相对较少的重大变化更好地使Move能够处理未来的进展。
这其中的许多变化增强了源语言,影响了编译器,而不需要对发布在链上的二进制表示进行任何更改。
现有的代码将继续编译,即使增加了这些新功能。由于这些功能是可选的,即使您的依赖项不包含它们,您也可以在您的packages中使用新功能进行编写。然而,在当前模块中选择利用新功能引入了一些重大变化。
阅读我们在Github上的迁移指南以获取完整的详细信息。
如何迁移
要将项目迁移到Move 2024 Beta版本,您有两个选项:
- 删除现有的
Move.lock
文件(如果存在),以确保您使用最新的sui-framework
版本。 - 运行
sui move migrate
。有关更多信息,请参阅迁移指南中的 自动迁移 部分。- 或者,更新您的
Move.toml
文件中的[package]
条目,将edition = "2024.beta"
包含在内。如果这样做,您可能会收到一些新错误,作为我们的 重大变化.
- 或者,更新您的
自动迁移
Move 2024包含一个自动迁移脚本,您可以在Move项目的根目录中调用 sui move migrate
来使用。运行该脚本时,您的控制台会提示您选择要使用的Move版本。如果您选择 2024.beta
,脚本将调用编译器,并尝试自动更新您的代码,以避免更新引入的 重大变化 (包括将结构标记为 public
、使用 mut
关键字标记可变变量、避免受限制的关键字、将 friends
for public(package)
,甚至在许多情况下更新路径为全局路径)。
在运行此脚本后,您的控制台会显示脚本打算进行的更改的差异。如果您接受更改,脚本将自动更新您的代码和 Move.toml
文件。您现在正在使用Move 2024 Beta。
新功能
以下是Move 2024中一些新功能的简要概述。
方法语法Method syntax
现在您可以使用 .
语法将某些函数作为方法调用。例如,以下调用:
vector::push_back(&mut v, coin::value(&c));
现在可以写成:
v.push_back(c.value());
在这个例子中,如果需要,方法的接收者(v
和 c
)会自动借用(分别为 &mut v
和 &c
)。
如果函数在与接收者类型相同的模块中定义,您可以将其作为方法调用,前提是它将接收者作为其第一个参数。
对于在模块外定义的函数,您可以使用 public use fun
和 use fun
.
索引语法Index syntax
使用方法语法,您可以将某些函数注释为 #[syntax(index)]
方法。然后,您可以使用 v[i]
形式的调用来调用这些方法。
例如:
*&mut v[i] = v[j];
可以解析为:
*vector::borrow_mut(&mut v, i) = *vector::borrow(&v, j);
public(package)
friend
声明以及相关的 public(friend)
可见性修饰符已经过时。取而代之的是 public(package)
可见性修饰符,它只允许在定义它们的同一包中调用函数。
位置字段Positional fields
现在您可以定义具有位置字段的结构,通过以零为基的索引来访问这些字段。例如:
public struct Pair(u64, u64) 具有复制、删除和存储功能;
然后访问每个字段:
public fun sum(p: &Pair): u64 {
p.0 + p.1
}
正如这个例子所示,您现在可以在结构字段列表之后声明能力。
嵌套use和标准库默认值
现在您可以为了更简洁性而嵌套 使用
别名。
use sui::{balance, coin::{Self, Coin}};
此外,以下use声明现在会自动包含在每个模块中:
use std::vector;
use std::option::{Self, Option};
use sui::object::{Self, ID, UID};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
相等性自动引用
相等性操作, ==
和 !=
,现在如果一侧是引用而另一侧不是,则会自动借用。例如:
fun check(x: u64, r: &u64): bool {
x == r
}
相当于:
fun check(x: u64, r: &u64): bool {
&x == r
}
这种自动借用可以发生在 ==
和 !=
.
循环标签
当嵌套循环时,直接跳转到外层循环可能更方便。例如:
let mut i = 0;
let mut j = 0;
let mut terminate_loop = false;
while (i < 10) {
while (j < 10) {
if (haystack(i, j) == needle) {
terminate_loop = true;
break;
};
j = j + 1;
};
if (terminate_loop) break;
i = i + 1;
}
现在,您可以直接为外部循环(在本例中为outer
)命名,并一次性中断它:
let mut i = 0;
let mut j = 0;
'outer: while (i < 10) {
while (j < 10) {
if (haystack(i, j) == needle) break'outer;
j = j + 1;
};
i = i + 1;
}
break
(带值的)
现在可以从循环中断中返回值。例如:
let mut i = 0;
let x: u64 = loop {
if (v[i] > 10) break i;
i = i + 1;
};
您也可以使用标签来实现这一点。例如:
let mut i = 0;
let mut j = 0;
let item = 'outer: loop {
while (j < 10) {
let item = haystack(i, j);
if (item == needle) break'outer option::some(item);
j = j + 1;
};
i = i + 1;
if (i == 10) break option::none();
};
重大变更
遗憾的是,Move 2024 中的重大变更正在增加。我们预计这些变更对现有代码的侵入性将最小化,并提供了迁移脚本,以在大多数情况下自动处理这些变更。此外,这些变更为 Move 2024 中即将推出的新功能铺平了道路。
数据类型可见性要求
目前,在Move中,所有结构体都是公共的:任何其他模块或包都可以导入它们,并按类型引用它们。为了使这一点更清晰,Move 2024要求所有结构体都必须使用public关键字声明。例如:
// legacy code
struct S { x: u64 }
// Move 2024 code
public struct S { x: u64 }
现在,任何非公共结构体都会在此时产生错误,而Move团队正在为未来的发布工作中探索新的可见性选项。
可变性要求
以前,在Move中,所有变量都是隐式可变的。例如:
fun f(s: S, y: u64): u64 {
let a = 0;
let S { x } = s;
a = 1;
x = 10;
y = 5;
x + y
}
现在,您必须明确声明可变变量:
fun f(s: S, mut y: u64): u64 {
let mut a = 0;
let S { mut x } = 5;
a = 1;
x = 10;
y = 5;
x + y
}
如果尝试在没有此明确声明的情况下重新分配或借用可变变量,则编译器将产生错误。
移除friends和 public(friend)
在Move的早期开发中引入了friends和 public(friend)
可见性,甚至早于包系统。如 public(package) 部分所示, public(package)
在Move 2024中取代了 public(friend)
。
下面的声明现在会产生错误:
module pkg::m {
friend pkg::a;
public(friend) fun f() { ... }
}
module pkg::a {
fun calls_f() { ... pkg::m::f() ... }
}
而如果想要使函数仅在包内可见,应该写成:
module pkg::m {
public(package) fun f() { ... }
}
module pkg::a {
// this now works directly
fun calls_f() { ... pkg::m::f() ... }
}
新关键字
展望未来,Move 2024 Beta为语言添加了以下关键字: enum
, for
, match
, mut
和 type
。不幸的是,如果在其他位置发现这些关键字,编译器现在会产生解析错误。随着语言的成熟,这是必要的变更。如果执行自动迁移,迁移工具将这些重命名为 enum
等,并重写代码以使用这些转义形式。
修订的路径和命名空间
与传统的Move相比,Move 2024对路径和命名空间的工作方式进行了修订,以便未来更轻松地处理 enum
别名。考虑以下来自 sui_system
库中测试注释的代码片段:
使用sui_system::sui_system;
...
#[expected_failure(abort_code =sui_system::validator_set::EInvalidCap)]
传统的Move总是将三部分名称视为地址(sui_system
)、模块(validator_set
)和模块成员(EInvalidCap
)。而Move 2024尊重 使用
的范围,因此属性中的 sui_system
解析为模块,在整体上产生名称解析错误。
为避免这种情况是预期行为的情况,Move 2024引入了全局资格的前缀操作。要使用它,可以将此注释重写为:
use sui_system::sui_system; ... #[expected_failure(abort_code = ::sui_system::validator_set::EInvalidCap)] // ^ note `::` here
迁移脚本尝试在可能的情况下使用全局资格来纠正命名错误。
一直前进
Move 2024 Beta版本除了上述的重大变更外,还带来了一些强大的新功能。未来还将有更多的功能。请加入Sui邮件订阅以了解今年即将推出的 Move 新功能,包括语法宏、带模式匹配的枚举和其他用户定义的语法扩展。