问题描述
使用Substrate区块链框架,如何在Substrate特定类型和Rust原语类型之间进行转换,反之亦然?
Using the Substrate blockchain framework, how can I convert between Substrate specific types and Rust primitive types and vice versa?
例如:
- 将时间(
T::Moment
)转换为u64
- 将u64转换为
T::Balance
- Convert a time (
T::Moment
) to au64
- Convert a u64 to a
T::Balance
等...
推荐答案
获取最新的Substrate master
基板已已删除As
,而赞成使用From
/. 假定所有类型至少为u32
.
For the latest in Substrate master
Substrate has removed As
in favor of From
/Into
. An assumption is made that all types are at least u32
.
根据特征SimpleArithmatic
,实现了以下内容:
From the trait SimpleArithmatic
, the following are implemented:
-
From
:u8
,u16
,u32
-
TryFrom
:u64
,u128
,usize
-
TryInto
:u8
,u16
,u32
,u64
,u128
,usize
From
:u8
,u16
,u32
TryFrom
:u64
,u128
,usize
TryInto
:u8
,u16
,u32
,u64
,u128
,usize
还提供了另一个特征以提供人体工程学当您不在乎该值是否饱和时,就可以进行无误的转换.
Another trait is also provided to provide ergonomicinfallible conversion when you don't care if the value saturates.
-
UniqueSaturatedInto
:u8
,u16
,u32
,u64
,u128
-
UniqueSaturatedFrom
:u64
,u128
UniqueSaturatedInto
:u8
,u16
,u32
,u64
,u128
UniqueSaturatedFrom
:u64
,u128
SaturatedConversion
(saturated_into
和saturated_from
).我唯一想到的是,这种情况在运行时算法中很深,在逻辑上可以确定它不会溢出,但是不能提供证明,因为它将取决于一致的预先存在的状态.
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
到承印物特定类型的工作应该很容易:
This means that working from u32
to Substrate specific types should be easy:
pub fn u32_to_balance(input: u32) -> T::Balance {
input.into()
}
对于较大的类型,您需要处理运行时Balance
类型小于可用类型的情况:
For larger types, you need to handle the case where the Balance
type for a runtime is smaller than what is available:
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原语时,还需要处理不兼容类型之间的转换:
When converting from T::Balance
to a rust primitive, you need to also handle conversion between incompatible types:
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
基板在sr-primitives
板条箱中提供 pub trait As<T>
:
For Substrate v1.0
Substrate provides 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;
}
以下是一些如何使用它的有效示例:
Here are some working examples of how it can be used:
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原语类型之间转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!