0%

Rust的Option细节

Rust中Option使用细节。

分类

unwrap系列

函数 功能 move panic evaluate
expect 取出v或panic Y Y N/A
unwrap 取出v或panic Y Y N/A
unwrap_or 取出v或默认值 Y N eagerly
unwrap_or_else 取出v或默认值 Y N lazily

map系列

函数 功能 move panic evaluate
map 把本Option<T>转化成Option<U>None Y N/A
map_or 把本Option<T>转化成U或默认值 Y eagerly
map_or_else 把本Option<T>转化成U或默认值 Y lazily

ok系列

函数 功能 move panic evaluate
ok_or 把本Option<T>转化成Result<T, E> Y eagerly
ok_or_else 把本Option<T>转化成Result<T, E> Y lazily

逻辑运算系列

函数 功能 move panic evaluate
and Option和参数optb有一个为None结果就为None Y eagerly
and_then Option和参数f()有一个为None结果就为None Y lazily
or Option和参数optb有一个为Some结果就为Some Y eagerly
or_else Option和参数f()有一个为Some结果就为Some Y lazily
xor Option和参数optb有且只有一个为Some结果才为Some Y N/A

细节

expect()

如果本OptionSome,就把值move出来;否则就以给定的msg来panic,和unwrap非常类似,只是panic产生的msg不同。

1
2
3
4
let o: Option<String> = Some(String::from("expect() moves the Option's value"));
let s = o.expect("oh no!"); //moved
println!("{}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
expect() moves the Option's value

unwrap()

如果本OptionSome,就把值move出来;否则就panic,和expect非常类似,只是panic产生的msg不同。

1
2
3
4
let o: Option<String> = Some(String::from("unwrap() moves the Option's value"));
let s = o.unwrap(); //moved
println!("{}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
unwrap() moves the Option's value

unwrap_or()

如果本OptionSome,就把值move出来;否则返回default。注意:default会被eagerly evaluated,也就是说,无论本OptionSome还是Nonedefault都先被求值。下面的unwrap_or_else与之相反。

1
2
3
4
5
6
7
8
9
10
11
fn get_string() -> String {
println!("get_string() is called");
String::from("world")
}

let o: Option<String> = Some(String::from(
"unwrap_or() moves the Option's value, and the default expression is eagerly evaluated",
));
let s = o.unwrap_or(get_string()); //moved, eagerly evaluated
println!("{}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
2
get_string() is called
unwrap_or() moves the Option's value, and the default expression is eagerly evaluated

unwrap_or_else()

如果本OptionSome,就把值move出来;否则返回f()。注意:f()会被lazily evaluated,也就是说,当且仅当本Option是一个Nonef()才被求值。上面的unwrap_or与之相反。

1
2
3
4
5
6
7
8
9
let o: Option<String> = Some(String::from(
"unwrap_or_else() moves the Option's value, and the default expression is lazily evaluated",
));
let s = o.unwrap_or_else(|| { //moved, lazily evaluated
panic!("closure called");
String::from("world")
});
println!("{}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
unwrap_or_else() moves the Option's value, and the default expression is lazily evaluated

map()

通过一个函数f(T)->U把本Option<T>转化成Option<U>而不是U);若本OptionNone,则返回None而不panic;

1
2
3
4
5
6
7
let o: Option<String> = Some(String::from("map() moves the Option's value"));
let s: Option<usize> = o.map(|str| { //moved
println!("{}", str);
str.len()
});
println!("{:?}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
2
map() moves the Option's value
Some(30)

map_or()

通过一个函数f(T)->U把本Option<T>转化成U而不是Option<U>);若本OptionNone,则返回default。注意:default会被eagerly evaluated,也就是说,无论是本OptionSome还是Nonedefault都先被求值。下面的map_or_else与之相反。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn get_usize() -> usize {
println!("get_usize() is called");
123
}

let o: Option<String> = Some(String::from(
"map_or() moves the Option's value, and the default expression is eagerly evaluated",
));
let s: usize = o.map_or(get_usize(), |str| { //moved
println!("{}", str);
str.len()
});
println!("{:?}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
2
3
get_usize() is called
map_or() moves the Option's value, and the default expression is eagerly evaluated
82

map_or_else()

通过一个函数f(T)->U把本Option<T>转化成U而不是Option<U>);若本OptionNone,则返回default。注意:default会被lazily evaluated,也就是说,当且仅当本Option是一个Nonedefault才被求值。上面的map_or与之相反。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let o: Option<String> = Some(String::from(
"map_or_else() moves the Option's value, and the default expression is lazily evaluated",
));
let s: usize = o.map_or_else(
|| {
panic!("closure called");
321
},
|str| {
println!("{}", str);
str.len()
},
);
println!("{:?}", s);
//println!("{:?}", o); //value borrowed here after move

输出:

1
2
map_or_else() moves the Option's value, and the default expression is lazily evaluated
86

ok_or()

把本Option<T>转化成Result<T, E>:若为Some(v)则结果为Ok(v);若为None则结果为Err(err)。注意:err会被eagerly evaluated,也就是说,无论本OptionSome还是Noneerr都先被求值。下面的ok_or_else与之相反。

1
2
3
4
5
6
7
8
9
fn get_usize() -> usize {
println!("get_usize() is called");
123
}

let o: Option<String> = Some(String::from("ok_or() moves the Option's value, and the error expression is eagerly evaluated"));
let r: Result<String, usize> = o.ok_or(get_usize());
println!("{:?}", r);
//println!("{:?}", o); //value borrowed here after move

输出:

1
2
get_usize() is called
Ok("ok_or() moves the Option\'s value, and the error expression is eagerly evaluated")

ok_or_else()

把本Option<T>转化成Result<T, E>:若为Some(v)则结果为Ok(v);若为None则结果为Err(err)。注意:err会被lazily evaluated,也就是说,当且仅当本Option是一个Noneerr才被求值。上面的ok_or与之相反。

1
2
3
4
5
6
7
let o: Option<String> = Some(String::from("ok_or_else() moves the Option's value, and the error expression is lazily evaluated"));
let r: Result<String, usize> = o.ok_or_else(||{
panic!("closure called");
123
});
println!("{:?}", r);
//println!("{:?}", o); //value borrowed here after move

输出:

1
Ok("ok_or_else() moves the Option\'s value, and the error expression is lazily evaluated")

and()

若本OptionSome则返回参数给定的optb;否则,本OptionNone,返回None。注意:optb会被eagerly evaluated,也就是说,无论本OptionSome还是Noneoptb都先被求值。下面的and_then与之相反。

可以理解成:*this && optb,二者若有一个为None则结果就是None,且逻辑表达式求值时不短路,即无论*this的结果是true还是false都要对optb求值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn get_option() -> Option<usize> {
println!("get_option() is called");
Some(123)
}

{
let o: Option<String> = Some(String::from("and() moves the Option's value, and the expression is eagerly evaluated"));
let u: Option<usize> = o.and(get_option());
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

{
let o: Option<String> = None;
let u: Option<usize> = o.and(get_option());
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

输出:

1
2
3
4
get_option() is called
Some(123)
get_option() is called
None

and_then()

若本OptionSome(v)则返回参数给定的f(v);否则,本OptionNone,返回None。注意:f()会被lazily evaluated,也就是说,当且仅当本Option是一个Somef()才被求值。上面的and与之相反。

可以理解成:*this && f(),二者若有一个为None则结果就是None,且逻辑表达式求值时会短路,即若*thisfalse,则不调用f(),直接返回;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
let o: Option<String> = Some(String::from("and_then() moves the Option's value"));
let u: Option<usize> = o.and_then(|str|{
Some(str.len())
});
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

{
let o: Option<String> = None;
let u: Option<usize> = o.and_then(|str|{
panic!("closure called");
Some(str.len())
});
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

输出:

1
2
Some(35)
None

or()

若本OptionSome则返回本Option;否则,返回参数给定的optb。注意:optb会被eagerly evaluated,也就是说,无论本OptionSome还是Noneoptb都先被求值。下面的or_else与之相反。

可以理解成:*this || optb,二者若有一个为Some则结果就是Some,且逻辑表达式求值时不短路,即无论*this的结果是true还是false都要对optb求值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn get_str_option() -> Option<String> {
println!("get_str_option() is called");
Some(String::from("world"))
}

{
let o: Option<String> = Some(String::from("or() moves the Option's value, and the expression is eagerly evaluated"));
let u: Option<String> = o.or(get_str_option());
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

{
let o: Option<String> = None;
let u: Option<String> = o.or(get_str_option());
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

输出:

1
2
3
4
get_str_option() is called
Some("or() moves the Option\'s value, and the expression is eagerly evaluated")
get_str_option() is called
Some("world")

or_else()

若本OptionSome则返回本Option;否则,返回参数给定的f()。注意:f()会被lazily evaluated,也就是说,当且仅当本Option是一个Nonef()才被求值。上面的or与之相反。

可以理解成:*this || f(),二者若有一个为Some则结果就是Some,且逻辑表达式求值时会短路,即若*thistrue,则不调用f(),直接返回;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
let o: Option<String> = Some(String::from("or_else() moves the Option's value, and the expression is lazily evaluated"));
let u: Option<String> = o.or_else(||{
panic!("closure is called");
Some(String::from("world"))
});
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

{
let o: Option<String> = None;
let u: Option<String> = o.or_else(||{
Some(String::from("world"))
});
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

输出:

1
2
Some("or_else() moves the Option\'s value, and the expression is lazily evaluated")
Some("world")

xor()

当且仅当本Option和参数optb二者之中有一个Some,才返回这个Some;否则返回None。注意,optb一定会被求值,因为只有求值才知道它是Some还是None

可以理解成:*this ^ optb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn get_str_option() -> Option<String> {
println!("get_str_option() is called");
Some(String::from("world"))
}

{
let o: Option<String> = Some(String::from("xor() moves the Option's value"));
let u: Option<String> = o.xor(get_str_option());
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

{
let o: Option<String> = None;
let u: Option<String> = o.xor(get_str_option());
println!("{:?}", u);
//println!("{:?}", o); //value borrowed here after move
}

输出:

1
2
3
4
get_str_option() is called
None
get_str_option() is called
Some("world")
写的不错,有赏!