[易学易懂系列|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::Option 和std::result::Result
以上,希望对你有用。
如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust
本人精通java高并发,DDD,微服务等技术实践,专注java,rust技术栈。 本人姓名郭莹城,坐标深圳,前IBM架构师、咨询师、敏捷开发技术教练,前IBM区块链研究小组成员、十多年架构设计工作经验,《区块链核心技术与应用》作者之一, 现聚焦于:区块链创投与交易所资源对接和技术咨询。 工作微信&QQ:360369487,区块链创投与交易所资源对接,加我注明:博客园+对接,技术咨询和顾问,加我注明:博客园+顾问。想学习golang和rust的同学,也可以加我微信,备注:博客园+golang或博客园+rust,谢谢!