14

使用 Substrate 区块链框架,我如何在 Substrate 特定类型和 Rust 原始类型之间进行转换,反之亦然?

例如:

  • 将时间 ( T::Moment) 转换为u64
  • 将 u64 转换为T::Balance

ETC...

4

1 回答 1

16

对于最新的 Substrate master

基板已删除As以支持From/ Into假设所有类型至少是u32.

从 traitSimpleArithmatic实现以下内容:

  • From: u8, u16,u32
  • TryFrom: u64, u128,usize
  • TryInto: u8, u16, u32, u64, u128,usize

当您不在乎值是否饱和时,还提供了另一个特性以提供符合人体工程学的可靠转换。

  • UniqueSaturatedInto: u8, u16, u32, u64,u128
  • UniqueSaturatedFrom: u64,u128

SaturatedConversion来自 Gav 的注意事项

SaturatedConversion(saturated_intosaturated_from) 不应该被使用,除非你知道你在做什么,你已经思考并考虑了所有的选项并且你的用例暗示饱和是基本正确的。我唯一一次想象这种情况是在运行时算术中很深,你在逻辑上确定它不会溢出,但不能提供证明,因为它取决于一致的预先存在的状态。

这意味着从u32特定类型到 Substrate 的工作应该很容易:

pub fn u32_to_balance(input: u32) -> T::Balance {
    input.into()
}

对于较大的类型,您需要处理Balance运行时类型小于可用类型的情况:

pub fn u64_to_balance_option(input: u64) -> Option<T::Balance> {
    input.try_into().ok()
}

// Note the warning above about saturated conversions
pub fn u64_to_balance_saturated(input: u64) -> T::Balance {
    input.saturated_into()
}

当转换T::Balance为 rust 原语时,您还需要处理不兼容类型之间的转换:

pub fn balance_to_u64(input: T::Balance) -> Option<u64> {
    TryInto::<u64>::try_into(input).ok()
}

// Note the warning above about saturated conversions
pub fn balance_to_u64_saturated(input: T::Balance) -> u64 {
    input.saturated_into::<u64>()
}

对于基板 v1.0

板条箱中提供pub trait As<T>sr-primitives基板:

/// Simple trait similar to `Into`, except that it can be used to convert numerics between each
/// other.
pub trait As<T> {
    /// Convert forward (ala `Into::into`).
    fn as_(self) -> T;
    /// Convert backward (ala `From::from`).
    fn sa(_: T) -> Self;
}

以下是一些如何使用它的工作示例:

impl<T: Trait> Module<T> {
    // `as_` will turn T::Balance into a u64
    pub fn balance_to_u64(input: T::Balance) -> u64 {
        input.as_()
    }

    // Being explicit, you can convert a `u64` to a T::Balance
    // using the `As` trait, with `T: u64`, and then calling `sa`
    pub fn u64_to_balance(input: u64) -> T::Balance {
        <T::Balance as As<u64>>::sa(input)
    }

    // You can also let Rust figure out what `T` is
    pub fn u64_to_balance_implied(input: u64) -> T::Balance {
        <T::Balance as As<_>>::sa(input)
    }

    // You can also let Rust figure out where `sa` is implemented
    pub fn u64_to_balance_implied_more(input: u64) -> T::Balance {
        T::Balance::sa(input)
    }
}
于 2019-05-10T15:59:27.987 回答