【Substrate 第一行代码】 substrate 关键 rust 语法

97 阅读1分钟

上一篇文章启动了 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-templatepallets/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-templatepallets/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 设置参数类型。