rust - 你如何在 Substrate 特定类型和 Rust 原始类型之间进行转换?
问题描述
使用 Substrate 区块链框架,我如何在 Substrate 特定类型和 Rust 原始类型之间进行转换,反之亦然?
例如:
- 将时间 (
T::Moment
) 转换为u64
- 将 u64 转换为
T::Balance
ETC...
解决方案
对于最新的 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_into
和saturated_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)
}
}
推荐阅读
- azure - 在本地开发中使用 azure KeyVault
- python - Python从位于url的图像计算phash
- javascript - 我如何在 discord js 中使用异步功能来制作问题游戏?
- python - 有没有办法根据它们的类型替换 Pandas 中的单元格?
- c++ - 为在 Visual Studio 中构建的 Qt 应用程序设置图标
- javascript - 使用 JavaScript 将时区偏移量列表更改为当前时间
- python - 如何使用 sql alchemy Flask 生成对给定 id 的用户名的引用?
- maxima - (wx)Maxima:多项式的字面顺序
- sql - 从存储在 postgresql 数据库中的 JSON 中选择文本或数字时遇到问题
- groovy - 使用 Groovy 解析嵌套 Json 中的值