⌘K

Custom Types

Icon Link结构体和枚举

你在 Sway 代码中定义的结构体和枚举将由 SDK 的 abigen! 宏自动生成对应的类型。

例如,如果你的 Sway 代码中有一个名为 CounterConfig 的结构体,如下所示:

struct CounterConfig {
  dummy: bool,
  initial_value: u64,
}

在使用了 abigen! 宏后,CounterConfig 将可以在你的 Rust 文件中访问!以下是一个示例:

abigen!(Contract(name="MyContract",
                 abi="e2e/sway/types/contracts/complex_types_contract/out/release/complex_types_contract-abi.json"));
 
// Here we can use `CounterConfig`, a struct originally
// defined in the contract.
let counter_config = CounterConfig {
    dummy: true,
    initial_value: 42,
};

你可以自由地在此范围内使用你的自定义类型(结构体或枚举)。这也意味着可以将自定义类型传递给函数,并从函数调用中接收

Icon Link泛型

Fuel Rust SDK 支持泛型枚举和泛型结构体。如果你已经熟悉 Rust,那么这是你典型的 struct MyStruct<T> 类型的泛型支持。

例如,你的 Sway 合约可能如下所示:

contract;

use std::hash::sha256;

struct SimpleGeneric<T> {
    single_generic_param: T,
}

abi MyContract {
  fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64>;
}

impl MyContract for Contract {
    fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64> {
        let expected = SimpleGeneric {
            single_generic_param: 123u64,
        };

        assert(arg1.single_generic_param == expected.single_generic_param);

        expected
    }
}

你的 Rust 代码将如下所示:

// simple struct with a single generic param
let arg1 = SimpleGeneric {
    single_generic_param: 123u64,
};
 
let result = contract_methods
    .struct_w_generic(arg1.clone())
    .call()
    .await?
    .value;
 
assert_eq!(result, arg1);

Icon Link未使用的泛型类型参数

Sway 支持在声明结构体/枚举时使用未使用的泛型类型参数:

struct SomeStruct<T, K> {
  field: u64
}

enum SomeEnum<T, K> {
  One: u64
}

如果你在 Rust 中尝试相同的操作,你会收到关于必须使用或删除 TK 的投诉。当为这些类型生成 Rust 绑定时,我们会使用 PhantomData Icon Link 类型。上述示例的生成绑定将如下所示:

struct SomeStruct<T, K> {
   pub field: u64,
   pub _unused_generic_0: PhantomData<T>
   pub _unused_generic_1: PhantomData<K>
}

enum SomeEnum<T, K> {
  One(u64),
  IgnoreMe(PhantomData<T>, PhantomData<K>)
}

为了减少对开发者体验的影响,你可以使用 SomeStruct::new 来初始化上述结构,而不需要处理 PhantomData

assert_eq!(
    <MyStruct<u16, u32>>::new(15),
    MyStruct {
        field: 15,
        _unused_generic_0: std::marker::PhantomData,
        _unused_generic_1: std::marker::PhantomData
    }
);

如果你的结构没有任何字段,我们也会派生 Default。至于枚举,所有的 PhantomData 都放在了一个名为 IgnoreMe 的新变体中,你需要在匹配中忽略它们:

match my_enum {
    MyEnum::One(_value) => {}
    MyEnum::IgnoreMe(..) => panic!("Will never receive this variant"),
}