Option
Option用于防止出现其他语言中的NullPointException。
Option出现在Java,Scala等语言中,非常好理解。
Option的定义:
enum Option<T> {
Some(T),
None,
}
例:创建一个Option值。注意泛型类型不能出错,否则编译器会报"mismatched types"。
let a = Some(100.111f32);
// 或
let a:Option<f32> = Some(100.111); //编译自动推导右值中的100.111为f32类型。
let b:Option<f32> = Some(100.111f32);
let c:Option<f64> = Some(100.111);
let d:Option<f64> = Some(100.111f64);
let s:Option<&str> = Some("i am a str");
防止空指针问题
Option类型主要就是用来处理空指针的。
例:函数返回Option值。
fn find(haystack: &str, needle: char) -> Option<usize> {
for (offset, c) in haystack.char_indices() {
if c == needle {
return Some(offset);
}
}
None
}
打印Option类型
使用{:?}
打印Option值
let a = Some(100.111);
println!("{:?}",a); // 打印:Some(100.111)
处理Option值
一般使用模式匹配来处理Option值。
例:
fn main() {
let file_name = "foobar.rs";
match find(file_name, '.') {
None => println!("No file extension found."),
Some(i) => println!("File extension: {}", &file_name[i+1..]),
}
}
解绑后计算
使用Option有个问题是无法对包装类型使用简单的运算。
例:a是一个Option类型无法运算。
let mut a:Option<i32> = Some(100);
a = a + 1; // 编译错误
需要使用match表达式将Option解构,然后重新运算赋值。
fn plus_one(x:Option<i32>) -> Option<i32> {
match x {
Some(i) => Some(i+1), // 解构后重新计算
None => None
}
}
fn main(){
let y:Option<i32> = Some(100);
let y = plus_one(y);
println!("{:?}",y);
}
Option的方法
Rust为Option提供了几个方法。
unwrap方法
该方法释放Option包裹的值。
方法定义:
impl<T> Option<T> {
fn unwrap(self) -> T {
match self {
Option::Some(val) => val,
Option::None =>
panic!("called `Option::unwrap()` on a `None` value"),
}
}
}
一个Option,值为None,调用unwrap()方法,会抛出一个panic(即一个退出程序的异常)
unwrap_or方法
方法定义:
fn unwrap_or<T>(option: Option<T>, default: T) -> T {
match option {
None => default,
Some(value) => value,
}
}
方法接受一个Option参数,若参数为None,则返回default的值,否则返回Some(T)中的值。
and_then方法
方法定义:
fn and_then<F, T, A>(option: Option<T>, f: F) -> Option<A>
where F: FnOnce(T) -> Option<A> {
match option {
None => None,
Some(value) => f(value),
}
}
该方法接收一个Option值与FnOnce的函数。
- 若Option值为None,则返回None。
- 若Option值为Some(T),则返回经FnOnce函数计算过的值。即
Option(f(T))
。