打赏

[易学易懂系列|rustlang语言|零基础|快速入门|(13)|Generics泛型]

[易学易懂系列|rustlang语言|零基础|快速入门|(13)]

有意思的基础知识

Generics泛型

我们今天来看看泛型。

什么是泛型?

我们来看看这样的情景:

我们要写一个函数,这个函数可以处理不同类型的值,但这个值的类型,在运行时,才由调用者确定。

我们不可能在函数方法中,一开始就写死。

那要什么办?

用泛型。

比如:用x : T替换x : u8

我们来看看例子:

泛型函数:

fn takes_anything<T>(x: T) { // x has type T, T is a generic type
}

fn takes_two_of_the_same_things<T>(x: T, y: T) { // Both x and y has the same type
}

fn takes_two_things<T, U>(x: T, y: U) { // Multiple types
}

泛型结构体:

struct Point<T> {
  x: T,
  y: T,
}

fn main() {
  let point_a = Point { x: 0, y: 0 }; // T is a int type
  let point_b = Point { x: 0.0, y: 0.0 }; // T is a float type
}

// 🔎 When adding an implementation for a generic struct, the type parameters should be declared after the impl as well
//   impl<T> Point<T> {

泛型枚举:

enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}

上面的枚举类型,Option,Result是Rust标准库里的泛型类型。

Option的值可能是Some或None,请看如下代码:

// 01 - - - - - - - - - - - - - - - - - - - - - -
fn get_id_by_username(username: &str) -> Option<usize> {
    // if username can be found in the system, set userId
    //    return Some(userId);//error here,userId should be a usize value
    	  return Some(12);//correct
    // else
        None
}

// 💭 So, on the above function, instead of setting return type as usize
//   set return type as Option<usize>
// Instead of return userId, return Some(userId)
//   else None (💡remember? last return statement no need return keyword and ending ;)

// 02 - - - - - - - - - - - - - - - - - - - - - -
struct Task {
    title: String,
    assignee: Option<Person>,
}

// 💭 Instead of assignee: Person, we use Option<Person>
// because the task has not been assigned to a specific person

// - - - - - - - - - - - - - - - - - - - - - - -
// When using Option types as return types on functions
// we can use pattern matching to catch the relevant return type(Some/None) when calling them

fn main() {
    let username = "anonymous";
    match get_id_by_username(username) {
        None => println!("User not found"),
        Some(i) => println!("User Id: {}", i)
    }
}

Result类型,一般用来处理错误信息。

例子如下:

// - - - - - - - - - - - - - - - - - - - - - -
fn get_word_count_from_file(file_name: &str) -> Result<u32, &str> {
  // if the file is not found on the system, return error
    return Err("File can not be found!");
  // else, count and return the word count
    // let mut word_count: u32; ....
    Ok(23)
}

// 💭 On the above function,
// instead panic(break) the app, when the file can not be found; return Err(something)
// or when it could get the relevant data; return Ok(data)


// - - - - - - - - - - - - - - - - - - - - - - -
// We can use pattern matching to catch the relevant return type(Ok/Err) when calling it

fn main() {
    let mut file_name = "file_a";
    match get_word_count_from_file(file_name) {
        Ok(i) => println!("Word Count: {}", i),
        Err(e) => println!("Error: {}", e)
    }
}

更多 Option 和Result 信息,请看: std::option::Optionstd::result::Result

以上,希望对你有用。

如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust

参考引用:https://learning-rust.github.io/docs/b4.generics.html

posted @ 2019-12-01 09:33  gyc567  阅读(292)  评论(0编辑  收藏  举报