Rust 学习笔记

#1 基础语法学习

#1.1 print

{:?} 可进行有格式的打印,是 Debug 宏的实现
#[derive(Debug)] 如要打印结构体数据 需要添加这个’宏定义’

#1.2 display

如果系统的 print 无法满足需求, 可自己实现 display 进行格式化打印。

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
use std::fmt; // Import the `fmt` module.

// Define a structure named `List` containing a `Vec`.
struct List(Vec<i32>);

impl fmt::Display for List {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Extract the value using tuple indexing,
// and create a reference to `vec`.
let vec = &self.0;

write!(f, "[")?;

// Iterate over `v` in `vec` while enumerating the iteration
// count in `count`.
for (count, v) in vec.iter().enumerate() {
// For every element except the first, add a comma.
// Use the ? operator to return on errors.
if count != 0 { write!(f, ", ")?; }
write!(f, "{}: {}", count, v)?;
}

// Close the opened bracket and return a fmt::Result value.
write!(f, "]")
}
}

fn main() {
let v = List(vec![1, 2, 3]);
println!("{}", v);
}

#1.3 trait

trait 实际就是接口的意思。trait 告诉 Rust 编译器某个特定类型拥有可能与其他类型共享的功能。可以通过 trait 以一种抽象的方式定义共享的行为。

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// 声明一个 summary 的 trait, 并且有默认的实现
pub trait Summary {
fn summarize(&self) -> String {
String::from("(read more...)")
}
}


pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}

// 对 NewsArticle 的 Summary 实现
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}

pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}

// 对 Tweet 的 Summary 实现
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}

pub struct NewComment {
pub author: String,
}

// 不实现自己的 Summary,使用默认实现
impl Summary for NewComment {}

// 使用 trait 作为参数,参数对象必须有 trait 的实现
// 可以传递任何 NewsArticle 或 Tweet 的实例来调用 notify。
// 任何用其它如 String 或 i32 的类型调用该函数的代码都不能编译,因为它们没有实现 Summary。

pub fn notify(item: impl Summary) {
println!("Breaking news {}",item.summarize());
}


fn main() {
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};

let article = NewsArticle {
headline: String::from("hello world"),
location: String::from("beijing"),
author: String::from("matianqi"),
content: String::from("read the book")
};

println!("1 new tweet: {}", tweet.summarize());

println!("1 new article: {}",article.summarize());

}

写法1

1
2
3
pub fn notify(item: impl Summary) {
println!("Breaking news! {}", item.summarize());
}

写法2

1
2
3
pub fn notify<T: Summary>(item: T) {
println!("Breaking news! {}", item.summarize());
}

上面的 写法1写法2 具有同样的效果,写法1impl trait , 写法2trait bound

通过 + 指定多个 trait bound

1
2
3
pub fn notify(item: impl Summary + Display) {}

pub fn notify<T: Summary + Display>(item: T) {}

当有多个泛型参数,使用where 从句指定 trait bound的语法。
这里实际上是 在where 中 描述了 函数泛型参数 具有哪些trait 。表现更规整。

1
2
3
4
5
6
7
fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32 {}

fn some_function<T, U>(t: T, u: U) -> i32
where T: Display + Clone,
U: Clone + Debug
{}

返回值使用 trait

1
2
3
4
5
6
7
8
fn returns_summarizable() -> impl Summary {
Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
}
}

使用 trait 求最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 这里还有另外一种写法是,返回值为 `slice` 中 `T` 的 引用
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
let mut largest = list[0];

for &item in list.iter() {
if item > largest {
largest = item;
}
}

largest
}

fn main() {
let number_list = vec![34, 50, 25, 100, 65];

let result = largest(&number_list);
println!("The largest number is {}", result);

let char_list = vec!['y', 'm', 'a', 'q'];

let result = largest(&char_list);
println!("The largest char is {}", result);
}

#1.4 函数定义

  • fn function_name(variable: String)接收了String,并拥有它。如果它不返回任何东西,那么这个变量就会在函数里面死亡。
  • fn function_name(variable: &String) 借用 String 并可以查看它
  • fn function_name(variable: &mut String)借用String,可以更改。

#2 rust优秀开源项目

#2.1 项目列表

TiKV
PingCAP公司开源的TiDB的存储引擎。(我也不知道是啥~~~)

mesalink
百度安全部,为解决OpenSSL心脏滴血等漏洞,用rust写的SSL实现。(目前好像没人维护了,Maintainer 去了google)