关于 modern-move-syntax
面向开发者和 AI Agent 的 Move 2024 语法参考技能,介绍集合、选项、循环、结构体和枚举中替代旧式调用的现代写法。
主要功能
- 01常见操作采用方法语法
- 02使用直接字符串和向量字面量
- 03应用选项与循环宏
- 04使用范围、折叠和筛选模式
- 05定义位置结构体和枚举
适用场景
- 01将旧式 Move 写法更新为现代语法
- 02简洁编写集合操作
- 03使用宏处理可选值
- 04通过枚举或位置字段建模数据
MCP 相关
环境支持时,建议查询 Sui 文档 MCP 服务 https://sui.mcp.kapa.ai,以核实指南并查找参考资料之外的细节。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mystenlabs/ skills --skill modern-move-syntax安装后在 Claude Code 中输入/modern-move-syntax确认已加载。
附带文件evals/code-evals.jsonevals/evals.json
详细介绍
modern-move-syntax
MCP 工具: 在你的环境中可用时,也请查询 Sui 文档 MCP 服务(
https://sui.mcp.kapa.ai),以获取最新答案。使用它进行验证,并了解这些参考文件未涵盖的细节。
概述
Move 2024 版引入了方法语法和若干便捷功能。AI Agent 经常会因训练数据而沿用 2024 版之前的函数调用模式。本技能涵盖所有现代语法模式。
所有模式均摘自 https://move-book.com/guides/code-quality-checklist
常见操作的方法语法
使用方法调用语法(点号表示法),而不是模块函数调用。
Coin 和 Balance
// WRONG — legacy function-call syntax
let value = coin::value(&payment);
let balance = coin::into_balance(payment);
balance::join(&mut pool.reserve, balance);
let coin = coin::from_balance(balance::split(&mut pool.reserve, amount), ctx);
// CORRECT — method syntax
let value = payment.value();
let balance = payment.into_balance();
pool.reserve.join(balance);
let coin = coin::from_balance(pool.reserve.split(amount), ctx);
// BEST — chained method calls
let balance = payment.split(amount, ctx).into_balance();
TxContext
// WRONG
tx_context::sender(ctx)
// CORRECT
ctx.sender()
UID 和 Object
// WRONG
object::delete(id);
// CORRECT
id.delete();
字符串字面量
直接使用带引号的字符串字面量,不要使用 std::string::utf8() 或字节字符串转换。
// WRONG
use std::string;
let s = string::utf8(b"hello");
// ALSO WRONG — unnecessary conversion
let s = b"hello".to_string();
// CORRECT — direct string literals (2024 edition)
let s = "hello"; // String (UTF-8)
let ascii = "hello"; // also works for ASCII strings
let s = b"hello".to_string(); // still valid but prefer quoted form
let ascii = b"hello".to_ascii_string(); // explicit ASCII when needed
Vector 字面量和方法
使用 vector 字面量语法和方法调用,而不是模块函数。
// WRONG
let mut v = vector::empty();
vector::push_back(&mut v, 10);
let first = vector::borrow(&v, 0);
let len = vector::length(&v);
// CORRECT
let mut v = vector[10];
let first = &v[0];
let len = v.length();
v.push_back(20);
集合索引语法
// WRONG
let val = vec_map::get(&map, &key);
// CORRECT
let val = &map[&key];
Option 宏
使用宏,而不是手动编写 is_some / destroy_some 模式。
// WRONG
if (opt.is_some()) {
let value = opt.destroy_some();
call_function(value);
};
// CORRECT
opt.do!(|value| call_function(value));
默认值
// WRONG
let value = if (opt.is_some()) { opt.destroy_some() } else { default };
// CORRECT
let value = opt.destroy_or!(default);
循环宏
// WRONG — manual counter loop
let mut i = 0;
while (i < 32) {
do_action();
i = i + 1;
};
// CORRECT — do! macro
32u8.do!(|_| do_action());
基于范围的循环
// Iterate over a numeric range
let mut sum = 0;
10u64.do!(|i| { sum = sum + i }); // i goes 0..9
// With index for more complex logic
let mut results = vector[];
5u64.do!(|i| results.push_back(i * i)); // [0, 1, 4, 9, 16]
Vector 迭代
// WRONG
let mut i = 0;
while (i < vec.length()) {
call_function(&vec[i]);
i = i + 1;
};
// CORRECT
vec.do_ref!(|e| call_function(e));
根据范围创建 Vector
// WRONG
let mut v = vector[];
let mut i = 0;
while (i < 32) { v.push_back(i); i = i + 1; };
// CORRECT
let v = vector::tabulate!(32, |i| i);
折叠和过滤
// fold
let sum = source.fold!(0, |acc, v| { acc + v });
// filter (requires T: drop)
let filtered = source.filter!(|e| e > 10);
结构体解包:.. 语法
在 2024 版中解构时,使用 .. 忽略未使用的字段。
// WRONG
let MyStruct { id, field_1: _, field_2: _, field_3: _ } = value;
// CORRECT
let MyStruct { id, .. } = value;
重命名的标准库函数
一些标准库函数已重命名。使用旧名称会产生弃用警告或编译错误。
// WRONG — deprecated, renamed
dynamic_field::exists_(&id, key)
// CORRECT
dynamic_field::exists(&id, key)
位置字段(元组结构体)
结构体可以使用位置字段,而不是命名字段:
// Named fields (traditional)
public struct Wrapper has copy, drop, store { value: u64 }
// Positional fields (2024 edition)
public struct Wrapper(u64) has copy, drop, store;
// Access by position
let w = Wrapper(42);
let val = w.0;
位置结构体适用于新类型包装器和动态字段键(参见 naming-conventions 技能)。
公有结构体
结构体上的 public 关键字控制其字段的可见性。不使用 public 时,字段仅在模块内可见——只有定义该结构体的模块才能构造或解构它。
// Fields visible only within this module
struct Config has key { id: UID, admin: address }
// Fields visible to other modules
public struct Token has key, store { id: UID, value: u64 }
当其他模块需要读取字段或构造/解构该结构体时,使用 public。若要实现封装,则省略它。
枚举
Move 2024 支持枚举类型:
public enum Color {
Red,
Green,
Blue,
Custom(u8, u8, u8),
}
public fun is_red(c: &Color): bool {
match (c) {
Color::Red => true,
_ => false,
}
}
枚举可以包含带位置字段、命名字段或不带字段的变体。使用 match 表达式进行穷尽式模式匹配。枚举不能具有 key 能力——它们本身不能直接成为对象,但可以作为字段存储在对象中。
快速参考
| 旧模式 | 现代 2024 语法 |
|---|---|
coin::value(&c) | c.value() |
coin::into_balance(c) | c.into_balance() |
balance::join(&mut b, v) | b.join(v) |
balance::split(&mut b, n) | b.split(n) |
tx_context::sender(ctx) | ctx.sender() |
object::delete(id) | id.delete() |
string::utf8(b"x") | "x" (或 b"x".to_string()) |
vector::empty() | vector[] |
vector::push_back(&mut v, x) | v.push_back(x) |
vector::length(&v) | v.length() |
opt.is_some() + destroy_some | opt.do!(|v| ...) |
while (i < n) { ... i++ } | n.do!(|_| ...) |
let S { a, b: _ } = x | let S { a, .. } = x |