peaq和rust

什么是peaq

区块链网络,类似物联网中的以太坊

Rust

环境安装

cargo是rust的包管理器

  1. 下载rustup
  2. 安装MSVC或MingGW
  3. 运行rustup,安装rustc和cargo

I/O

宏规则

println!()print!():前面的换行

1
print!("x = {0}", x)

数据类型

整型:i32有符号32位,u64无符号64位

浮点数:默认64位精度

布尔型

字符:一个char有4个字节,用utf-8表示

元组:()

数组:[]

函数

传入参数时需指定类型

1
2
3
fn foo(x:i32, y:u64){
print!(x, y)
}

函数体表达式:块中最后为一个没有;的表达式,用来返回值

1
2
3
4
fn foo(x:i32) -> i32 {
x+1
return x+1;
}

条件语句

条件表达式必须为布尔型,不适用c++中的“非0即真”

可用if-else结构和函数体表达式实现a?b:c的效果

循环语句

for(int i=0; i<10; i++){}的用法,用while i<10 {i=i+1}代替

可以for x in array.iter(){}for x in 0..5 {}

无限循环:loop{break ret;},ret为返回值

重影

重影:指变量的名称可以被重新使用的机制

不可变变量:let a = 123;

可变变量:let mut a = 123;

常量:const a = 123;

重影与可变变量:重影可改变变量的类型,可变属性和值,而可变变量仅可改变值

所有者

为了让 Rust 在编译阶段更有效地分析内存资源的有用性以实现内存管理而诞生的概念

所有权有以下三条规则:

  • Rust 中的每个值都有一个变量,称为其所有者。
  • 一次只能有一个所有者。
  • 当所有者不在程序运行范围时,该值将被删除。

变量范围:从声明变量开始有效直到变量所在域结束

移动

1
2
let a = xxx;
let b = a;

对以上情况有:

  1. 栈中:基本数据,直接复制成两份数据,比如整型,浮点数等等
  2. 堆中:不定长数据,将释放前一变量,比如string等等

克隆

对于上面堆中数据确实需要复制成两份的情况,可以这样做:

1
2
let a = String::from("helloRust");
let b = a.clone();

传参

同移动,基本数据传完后依旧可以使用,不定长数据传完即被移动

引用

1
2
let s1 = String::from("hello");
let s2 = &s1;

这里s1并不会被释放,s2指向s1,s1再指向堆中的数据。

引用仅租借所有权,如果所有权移动了则需要重新租借。

可变引用可以修改原变量的值let b = &mut a;

可变引用不允许多重引用,但不可变引用可以。

垂直引用

指针指向NULL或者被释放的变量。

Rust中不允许垂直指针存在。

切片

let part = &str[0..5];

切片结果必须是引用类型。

..yx....都是符合语法的。

被切片的变量禁止修改值。

String和str:不一样的类型,切片结果都是&str类型

可以通过&string[..]将String转换成str

结构体

1
2
3
4
5
6
7
8
9
10
struct Foo{
name: String,
Age: u32
}
// 定义Foo
let a = Foo{
name: String::from("henry"),
Age: 18
};
//实例化Foo
1
2
3
4
5
6
7
//结构体更新
let b = Foo2{
name: String::from("five"),
..a
};
//b的Age和a不同,其他字段相同
//能不能完全复制,直接..a
1
2
3
4
5
//元组结构体
struct Color(u8, u8, u8);
let black = Color(0,0,0)
//通过下标访问
println!("{}", black.1);
1
2
3
4
5
6
7
8
9
10
//输出结构体
#[derive(Debug)]

struct Rectangle {
width: u32,
height: u32,
}

println!("{:?}", Rectangle);
println!("{:#?}", Rectangle);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//结构体方法
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
//结构体关联函数,不依赖实例
impl Rectangle1 {
fn create(width: u32, height: u32) -> Rectangle {
Rectangle{width, height}
}
}

fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!("rect1's area is {}", rect1.area());
}

生命周期

重要,但没细看qaq

1
2
3
4
//生命周期注释
&i32 // 常规引用
&'a i32 // 含有生命周期注释的引用
&'a mut i32 // 可变型含有生命周期注释的引用

静态生态周期:’static,生命周期为程序运行期间

1
2
3
4
5
6
7
8
9
10
11
12
13
//泛型+特性+生命周期
use std::fmt::Display;

fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str
where T: Display
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}

泛型与特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//函数中泛型
fn max<T>(array: &[T]) -> T {
let mut max_index = 0;
let mut i = 1;
while i < array.len() {
if array[i] > array[max_index] {
max_index = i;
}
i += 1;
}
array[max_index]
}
//<T>
//可以用<T1, T2>表示不同数据类型

//结构体,枚举类和方法中泛型
//struct Foo<T>{}
//impl<T> Foo<T>{}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//特性
trait Descriptive {
fn decribe(&self) -> String {
//默认特性
String:: from("[Object]")
}
}

struct Foo {
name: String,
age: u8
}

impl Descriptive for Foo {
fn describe(&self) -> String{
//重新定义特性
format!("{} {}", self.name, self.age)
}
}
//特性作为函数参数,这样在函数内可调用该特性规范的方法
fn output<T: Descriptive>(object: T) {
println!("{}", object.describe());
}
fn output_two<T: Descriptive>(arg1: T, arg2: T) {
println!("{}", arg1.describe());
println!("{}", arg2.describe());
}
//多个特性
fn notify(item: impl Summary + Display)
fn notify<T: Summary + Display>(item: T)
//可以简化
fn some_function<T, U>(t: T, u: U) -> i32
where T: Display + Clone,
U: Clone + Debug
//特性做返回值,
//特性做返回值只接受实现了该特性的对象做返回值
//且在同一个函数中所有可能的返回值类型必须完全一样
fn person() -> impl Descriptive {
Person {
name: String::from("Cali"),
age: 24
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//泛型+特性例子
trait Comparable {
fn compare(&self, object: &Self) -> i8;
}

fn max<T: Comparable>(array: &[T]) -> &T {
let mut max_index = 0;
let mut i = 1;
while i < array.len() {
if array[i].compare(&array[max_index]) > 0 {
max_index = i;
}
i += 1;
}
&array[max_index]
}

impl Comparable for f64 {
fn compare(&self, object: &f64) -> i8 {
if &self > &object { 1 }
else if &self == &object { 0 }
else { -1 }
}
}

fn main() {
let arr = [1.0, 3.0, 5.0, 4.0, 2.0];
println!("maximum of arr is {}", max(&arr));
}