[易学易懂系列|rustlang语言|零基础|快速入门|(13)]
有意思的基础知识
Generics泛型
我们今天来看看泛型。
什么是泛型?
我们来看看这样的情景:
我们要写一个函数,这个函数可以处理不同类型的值,但这个值的类型,在运行时,才由调用者确定。
我们不可能在函数方法中,一开始就写死。
那要什么办?
用泛型。
比如:用x : T替换x : u8
我们来看看例子:
泛型函数:
1
2
3
4
5
6
7
8
9 1fn takes_anything<T>(x: T) { // x has type T, T is a generic type
2}
3
4fn takes_two_of_the_same_things<T>(x: T, y: T) { // Both x and y has the same type
5}
6
7fn takes_two_things<T, U>(x: T, y: U) { // Multiple types
8}
9
泛型结构体:
1
2
3
4
5
6
7
8
9
10
11
12
13 1struct Point<T> {
2 x: T,
3 y: T,
4}
5
6fn main() {
7 let point_a = Point { x: 0, y: 0 }; // T is a int type
8 let point_b = Point { x: 0.0, y: 0.0 }; // T is a float type
9}
10
11// ? When adding an implementation for a generic struct, the type parameters should be declared after the impl as well
12// impl<T> Point<T> {
13
泛型枚举:
1
2
3
4
5
6
7
8
9
10 1enum Option<T> {
2 Some(T),
3 None,
4}
5
6enum Result<T, E> {
7 Ok(T),
8 Err(E),
9}
10
上面的枚举类型,Option,Result是Rust标准库里的泛型类型。
Option的值可能是Some或None,请看如下代码:
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 1// 01 - - - - - - - - - - - - - - - - - - - - - -
2fn get_id_by_username(username: &str) -> Option<usize> {
3 // if username can be found in the system, set userId
4 // return Some(userId);//error here,userId should be a usize value
5 return Some(12);//correct
6 // else
7 None
8}
9
10// ? So, on the above function, instead of setting return type as usize
11// set return type as Option<usize>
12// Instead of return userId, return Some(userId)
13// else None (?remember? last return statement no need return keyword and ending ;)
14
15// 02 - - - - - - - - - - - - - - - - - - - - - -
16struct Task {
17 title: String,
18 assignee: Option<Person>,
19}
20
21// ? Instead of assignee: Person, we use Option<Person>
22// because the task has not been assigned to a specific person
23
24// - - - - - - - - - - - - - - - - - - - - - - -
25// When using Option types as return types on functions
26// we can use pattern matching to catch the relevant return type(Some/None) when calling them
27
28fn main() {
29 let username = "anonymous";
30 match get_id_by_username(username) {
31 None => println!("User not found"),
32 Some(i) => println!("User Id: {}", i)
33 }
34}
35
Result类型,一般用来处理错误信息。
例子如下:
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 1// - - - - - - - - - - - - - - - - - - - - - -
2fn get_word_count_from_file(file_name: &str) -> Result<u32, &str> {
3 // if the file is not found on the system, return error
4 return Err("File can not be found!");
5 // else, count and return the word count
6 // let mut word_count: u32; ....
7 Ok(23)
8}
9
10// ? On the above function,
11// instead panic(break) the app, when the file can not be found; return Err(something)
12// or when it could get the relevant data; return Ok(data)
13
14
15// - - - - - - - - - - - - - - - - - - - - - - -
16// We can use pattern matching to catch the relevant return type(Ok/Err) when calling it
17
18fn main() {
19 let mut file_name = "file_a";
20 match get_word_count_from_file(file_name) {
21 Ok(i) => println!("Word Count: {}", i),
22 Err(e) => println!("Error: {}", e)
23 }
24}
25
更多 Option 和Result 信息,请看: std::option::Option 和std::result::Result
以上,希望对你有用。
1
2 1如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust
2