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

例如:

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

推荐答案

For the latest in Substrate master

基板上有removed As个有利于From/Into.An assumption is made that all types are at least 103.

根据trait 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 100 from Gav

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

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

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

For 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相关问答推荐

阻止websocket中断的中断中断的终端(操作系统错误4)

关联类型(类型参数)命名约定

下载压缩文件

如何将`Join_all``Vec<;Result<;Vec<;Foo&>;,Anywhere::Error&>;`合并到`Result<;Vec<;Foo&>;,Anywhere::Error&>;`

为什么Rust函数的移植速度比C++慢2倍?

你是如何在铁 rust 一侧的金牛座获得应用程序版本的?

是否可以使用Rust宏来构建元组的项?

正则表达式中的重叠匹配?(铁 rust 正则式发动机)

如何使用RefCell::JOYMOMTborrow 对 struct 不同字段的可变引用

作为1字节位掩码的布尔值 struct

如何实现Serde::Ser::Error的调试

正在将带有盒的异步特征迁移到新的异步_fn_in_特征功能

在 Rust 中,在需要引用 self 的 struct 体方法中使用闭包作为 while 循环条件

Rust Option 的空显式泛型参数

将多维数组转换为切片

Rust 为什么被视为borrow ?

为什么需要同时为值和引用实现`From`?方法不应该自动解引用或borrow 吗?(2023-06-16)

(let b = MyBox(5 as *const u8); &b; ) 和 (let b = &MyBox(5 as *const u8); ) 之间有什么区别

在构建器模式中捕获 &str 时如何使用生命周期?

为什么-x试图解析为文字并在声明性宏中失败?