Sui.

帖子

分享您的知识。

HaGiang.
Apr 30, 2025
专家问答

有什么办法可以解决这类问题吗?

我正在开发一个Move模块,在尝试将泛型结构的字段传递给函数时遇到了类型错误. 以下是我所拥有内容的简化版本:

  • Sui
3
2
分享
评论
.

答案

2
harry phan.
Apr 30 2025, 03:19

在 Move 中,你遇到了一个实际上是设计所造成的限制. 即使你的泛型���型 T 受到 key + store 的限制,编译器仍然对 T 中的字段一无所知. 密钥能力只是确保 T 包含 UID,但它更像是一种类型系统规则,而不是编译器推断结构的方式. 因此,在编译时,T 具有 id 字段不是你可以依赖的.

同样重要:Move 中的字段访问仅限于定义结构的模块. 因此,即使 T 不是通用的,如果它来自另一个模块,你仍然无法直接访问它的字段.

你想要做的事情 —— 从通用对象传递 &mut my_obj.id —— 是不可能的,这是故意的. 它可以保护 Move 中的关键不变量,尤其是在UID安全方面. 允许对诸如UID之类的字段进行通用可变访问将违反该语言的核心安全保障.

如果你的目标是使用 df:: add,并且你正在尝试将一个字段附加到对象的 UID,则需要重构代码. 一种方法是完全绕过泛型然后编写:

public fun add_df(uid: &mut UID, new_id: ID) {
    df::add(uid, b"aaa".to_string(), new_id);
}

如果你能安全地访问 &mut UID,这就行得通了,但这是一个敏感的操作——除非你完全确定其影响,否则你应该避免暴露对 UID 的可变引用.

如果您的应用程序仅使用几种已知的结构类型,则另一种实用的解决方案是为每种类型编写单独的逻辑,而不使用泛型.

为了更深入地了解动态字段的工作原理以及如何围绕 UID 访问进行设计,我强烈推荐 Move Book 中的本章:https://move-book.com/programmability/dynamic-fields.html#dynamic-fields

4
最佳答案
评论
.
0xduckmove.
Apr 30 2025, 03:23

你应该知道两件事:

  1. 只能在定义结构的模块中访问字段. 因此,即使没有泛型,你也无法访问外来类型的字段.
  2. 我想我明白你来自哪里:key forces id: UID 字段,但它只是额外的 “验证器规则”,对编译器来说不是提示. 换句话说,编译器不知道 T 有任何字段,也不应该知道
3
评论
.

你知道答案吗?

请登录并分享。

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

610帖子1335答案
Sui.X.Peera.

赚取你的 1000 Sui 份额

获取声誉积分,并因帮助 Sui 社区成长而获得奖励。

奖励活动七月