rust - 如何在 Substrate 特定类型和 Rust 原始类型之间进行转换?

标签 rust blockchain substrate

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

例如:

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

等...

最佳答案

最新的 Substrate master

基板有 removed As 赞成From/Into . 假设所有类型至少为 u32 .

来自特征 SimpleArithmatic ,实现了以下内容:

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

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

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

NOTE on SaturatedConversion from Gav

SaturatedConversion (saturated_into and saturated_from) should not be used unless you know what you're doing, you've thought and considered all options and your use-case implies that saturation is fundamentally correct. The only time I imagine this is the case is deep in runtime arithmetic where you are logically certain it will not overflow, but can't provide a proof because it would depend on consistent pre-existing state.

这意味着从 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>()
}

对于 Substrate v1.0

基板提供 pub trait As<T> in the sr-primitives crate :

/// 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)
    }
}

关于rust - 如何在 Substrate 特定类型和 Rust 原始类型之间进行转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56081117/

相关文章:

docker - 如何使用用于REST通信的端口映射Hyperledger Fabric对等体(2nd,3rd,4th)

rust - 在事件类型之间转换

rust - 如何在Rust中返回gpio_cdev::Error?

rust - 为什么Rust中的默认行为是执行赋值移动,而不是仅仅为该值创建另一个 “reference”?

rust - 错误 "closure may outlive the current function"的真正含义是什么?

rust - 递归结构的最佳实现是什么?

blockchain - x509 : ECDSA verification failure

go - Hyperledger编程中如何使用stub.CreateTable

substrate - 我们可以在基质中使用不同的地址格式吗?

rust - 如何从底物中的子树中获取根哈希或证明?