move泛型个人理解

  • obj3ct
  • 发布于 2025-03-04 22:59
  • 阅读 240

个人对泛型概念的一点理解

定义

泛型是 Move 语言中的一个重要特性,泛型的存在允许编写可以处理多种类型的同一套业务逻辑代码,而不需要为每种类型重复编写相同的逻辑,减少了工作量。泛型可以应用于结构体和函数,使得代码更加灵活和可复用。

泛型的使用

struct Box<T> {
    value: T
}

fun create_box<T>(value: T): Box<T> {
    Box { value }
}

这个Box结构体里的T是类型参数,这个结构体的意思是这个Box里面的value值可以为任意的类型 这个函数的输入参数value和返回值Box都是泛型类型

能力约束示例

// 定义具有 copy 能力的泛型结构体
struct CopyableBox<T: copy> {
    value: T
}

// 定义具有 copy 和 drop 能力的泛型函数
fun create_copyable_box<T: copy + drop>(value: T): CopyableBox<T> {
    CopyableBox { value }
}

注意到这里面两个geT是同一个类型变量,但是拥有不同的能力,这又是怎么回事? 原因:泛型类型的能力约束是累加的,必须同时满足整个合约里面出现的所有能力约束

泛型的特点

代码复用

通过泛型,一套业务逻辑可以用在多个类型的变量上,避免重复代码,减小了很多工作量。

类型安全

考虑类型安全,就不可避免地要理解phantom 参数 与泛型的关联

这一个我也不知道怎么表述,就用例子说明一下吧 例1

// 定义一个标记单位类型的 phantom 泛型参数
struct Value<phantom T> {
    amount: u64
}

// 定义不同的单位类型
struct Meter {} // 表示米
struct Kilogram {} // 表示千克

// 使用 Value 结构体
fun main() {
    let length = Value<Meter> { amount: 10 }; // 10 米
    let weight = Value<Kilogram> { amount: 5 }; // 5 千克

    // 以下代码会报错,因为类型不匹配
    // let invalid = length + weight; // 错误:Meter 和 Kilogram 是不同的类型
}

phantom 与 类型安全

注意到这里用不同结构体来表示不同的单位,然后在实例化时选择T的类型为这个结构体,通过 Value<Meter> 和 Value<Kilogram>应用了不同结构体定义的单位,编译器可以区分 length 和 weight 是不同的类型,即使它们的内部数据(amount)类型相同。 以下是例2

// 定义一个标记单位类型的 phantom 泛型参数
struct Value&lt;phantom T: copy + drop> {
    amount: u64
}

// 定义不同的单位类型
struct Meter has copy , drop {} // 表示米
struct Kilogram has copy , drop {} // 表示千克
struct Gram has copy  {} //表示克

// 使用 Value 结构体
fun main() {
    let length = Value&lt;Meter> { amount: 10 }; // 10 米
    let weight = Value&lt;Kilogram> { amount: 5 }; // 5 千克

    // 以下代码会报错,因为不符合能力约束,类型不匹配
    let weight = Value&lt;Gram> { amount: 5 }; 
}

避免冗余存储

仔细查看前面例子(例1or例2)里的phantom T会发现其内部的amount类型是u64而不是T,这就是phantom参数的特性,而避免冗余存储我个人的理解是:如果参数的类型是是T,那么就说明类型很可能是已知的任意一种类型或还没有发布的类型,这个时候预留的存储空间就需要尽量大一些以防存储空间不足导致无法兼容一些未来可能推出的新类型;而在phantom参数作用下amount类型是u64而不是T,这就只需要保留足够u64类型的存储空间就够了 Value 结构体只存储了 amount 字段(u64 类型),而 T 作为 phantom 参数不占用实际存储空间 注:phantom T类型结构体的内部参数可以全部和T类型无关,而普通泛型参数T不可以

  • 原创
  • 学分: 7
  • 分类: Move
  • 标签:
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。
该文章收录于 sui_从task到实战
2 订阅 5 篇文章

0 条评论

请先 登录 后评论
obj3ct
obj3ct
江湖只有他的大名,没有他的介绍。