如何使用 Substrate 区块链框架在 Substrate 特定类型和 Rust 原始类型之间进行转换?
例如:
- 将时间(
T::Moment
)转换为u64
- 将
u64
转换为T::Balance
等等...
如何使用 Substrate 区块链框架在 Substrate 特定类型和 Rust 原始类型之间进行转换?
例如:
T::Moment
)转换为 u64
u64
转换为 T::Balance
等等...
Substrate已经移除了As
,改为使用From
/Into
。 假设所有类型至少为u32
。
从trait SimpleArithmatic
中,实现了以下内容:
From
:u8
、u16
、u32
TryFrom
:u64
、u128
、usize
TryInto
:u8
、u16
、u32
、u64
、u128
、usize
另外提供了一个trait以实现舒适的不可失败转换,当您不在意值是否饱和时可以使用。
UniqueSaturatedInto
:u8
、u16
、u32
、u64
、u128
UniqueSaturatedFrom
:u64
、u128
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 提供了 sr-primitives
包中的 pub trait As<T>
:
/// 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)
}
}
As
,而改用From/Into
。 - Bryan Chensaturated_into()
来实现,但是一旦你的块编号超过255,返回的值将会被固定在255,并且可能没有什么用处。 - Shawn Tabrizi//declare following import
use frame_support::sp_runtime::traits::Zero;
use frame_support::sp_runtime::SaturatedConversion;
//then saturated_into can be used to convert number into Balance type as follows
let cost_in_u64: u64 = 250; //or expression like 200 + 50;
let cost: BalanceOf<T> = cost_in_u64.saturated_into::<BalanceOf<T>>();
//convert 1010 of type u32 into Balance
let cost2: BalanceOf<T> = 1010u32.into();
//set zero balance
let cost3 = BalanceOf::<T>::zero();
在cfg中,BalanceOf的定义如下:
#[cfg(feature = "std")]
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;