【问题标题】:How to use generic structs in the Parity Substrate custom runtime?如何在 Parity Substrate 自定义运行时中使用泛型结构?
【发布时间】:2019-01-11 13:53:09
【问题描述】:

我想在 Parity Substrate 自定义运行时中使用 Struct 创建一个数据类型。数据类型旨在是通用的,以便我可以在不同的类型上使用它。

我正在尝试以下,但它没有编译。编译器抱怨找不到 T 的子类型。

pub struct CustomDataType<T> {
    data: Vec<u8>,
    balance: T::Balance,
    owner: T::AccountId,
}

我应该能够编译通用结构。

【问题讨论】:

  • 编译器将不知道关联类型 BalanceAccountId 来自何处,除非您在 T 上应用提供它们的特征绑定。下一次,请看看什么是正确的minimal reproducible example,不要忘记包含相关的 crates 和模块。
  • 请查看如何创建minimal reproducible example,然后查看edit 您的问题以包含它。我们无法分辨代码中存在哪些 crate、类型、特征、字段等。尝试在Rust Playground 上重现您的错误,或者您可以在全新的 Cargo 项目中重现它。还有Rust-specific MCVE tips

标签: rust substrate


【解决方案1】:

很遗憾,the answer that Sven Marnach gives 在 Parity Substrate 的上下文中不起作用。在结构顶部使用了额外的派生宏,这些宏在沿着“直观”路径前进时会导致问题。

在这种情况下,您应该将所需的特征直接传递到您的自定义类型中,并为结构的上下文创建新的泛型。

类似这样的:

use srml_support::{StorageMap, dispatch::Result};

pub trait Trait: balances::Trait {}

#[derive(Encode, Decode, Default)]
pub struct CustomDataType <Balance, Account> {
    data: Vec<u8>,
    balance: Balance,
    owner: Account,
}

decl_module! {
    // ... removed for brevity
}

decl_storage! {
    trait Store for Module<T: Trait> as RuntimeExampleStorage {
        Value get(value): CustomDataType<T::Balance, T::AccountId>;
    }
}

我们刚刚创建了a doc for this exact scenario,希望对您有所帮助。

【讨论】:

    【解决方案2】:

    看起来T::BalanceT::AcountId 是某些特征的关联类型,因此它们只能在为T 实现该特征(例如MyTrait)时使用。你可以告诉编译器 T 实现了 MyTrait 通过添加一个 trait bound:

    pub struct CustomDataType<T: MyTrait> {
        data: Vec<u8>,
        balance: T::Balance,
        owner: T::AccountId,
    }
    

    一般来说,如果类型受到适当类型边界的限制,您只能假定泛型类型的属性、方法和关联类型。 (唯一的例外是默认情况下假定类型参数为 sized,因此您可以在没有明确限制的情况下进行此假设。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      • 2023-03-14
      相关资源
      最近更新 更多