上一篇文章启动了 node template 模板代码,但是在看代码的时候因为对 rust 不太了解所有有一些困难,在这里整理一下自己学习遇到的问题。
完整的 rust 语法学习可以参考course.rs/basic/trait…
在 substrate 开发中 自定义 pallet 模块是主要的开发场景,可以说大部分 substrate 开发工作就是在开发 pallet 。rust 的 trait 特性支撑着 pallet 运行,先了解 trait 有助于我们更好的阅读源码。
trait 关联类型指定占位类型
先看代码
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
实现这个 trait
struct Counter {
value: u32
}
impl Iterator for Counter {
type Item = u32; // 定义Item类型
fn next(&mut self) -> Option<Self::Item> { // 返回值为Option<Self::Item>
if self.value < 3 {
self.value += 1;
Some(self.value)
} else {
None
}
}
}
let mut counter = Counter {
value: 0
};
println!("{:?}", counter.next()); // Some(1)
println!("{:?}", counter.next()); // Some(2)
println!("{:?}", counter.next()); // Some(3)
println!("{:?}", counter.next()); // None
在substrate-node-template
中 pallets/template/src/lib.rs
我们可以看到这样的使用
/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
pub trait Config: frame_system::Config {
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
}
runtime/src/lib.rs
/// Configure the pallet-template in pallets/template.
impl pallet_template::Config for Runtime {
type Event = Event;
}
trait 继承
trait 只能支持 trait 之间的继承
trait B{}
trait A: B{}
当实现 A的时候 需要实现 A 的所有父 trait。
trait bond 约束
struct Rectangle{length:f64, height:f64} // 定义矩阵
struct Triangle{length:f64, height:f64} // 三角形
trait HasArea {
fn area(&self) ->f64;
}
impl HasArea for Rectangle{
fn area(&self) ->f64 { self.length * self.height}
}
impl HasArea for Triangle{
fn area(&self) ->f64 { 0.5 * self.length * self.height}
}
// `T`必须实现`HasArea`。任意符合该约束的泛型的实例,都可访问`HasArea`的`area`函数
fn area<T:HasArea>(t:&T)->f64 {t.area()}
fn main() {
let rectangle = Rectangle{length:10.0,height:20.0};
let _triangle = Triangle{length:20.0,height:10.0};
print_debug(&rectangle);
println!("Rectangle Area is : {}",area(&rectangle));
println!("Triangle Area is : {}",area(&_triangle));
}
在substrate-node-template
中 pallets/template/src/lib.rs
有大量使用 <T:Config>
来使用Config 中的状态。
pub enum Event<T: Config> {
/// Event documentation should end with an array that provides descriptive names for event
/// parameters. [something, who]
SomethingStored(u32, T::AccountId),
}
总结
初始化 pallet 可以看成是定义 trait 然后在 runtime 中的 Runtime 实现。后面我们在展示自定义 pallet 支持在 runtime 设置参数类型。