我经常Option<String>从计算中获得一个,我想使用这个值或默认的硬编码值.
这对于一个整数来说是微不足道的:
let opt: Option<i32> = Some(3);
let value = opt.unwrap_or(0); // 0 being the default
Run Code Online (Sandbox Code Playgroud)
但是使用a String和a &str,编译器会抱怨类型不匹配:
let opt: Option<String> = Some("some value".to_owned());
let value = opt.unwrap_or("default string");
Run Code Online (Sandbox Code Playgroud)
这里的确切错误是:
error[E0308]: mismatched types
--> src/main.rs:4:31
|
4 | let value = opt.unwrap_or("default string");
| ^^^^^^^^^^^^^^^^
| |
| expected struct `std::string::String`, found reference
| help: try using a conversion method: `"default string".to_string()`
|
= note: expected type `std::string::String`
found type `&'static str`
Run Code Online (Sandbox Code Playgroud)
一种选择是将字符串切片转换为拥有的String,如rustc所示:
let value …Run Code Online (Sandbox Code Playgroud) 我首先想到的是map对Option的,但我不能用try!从封闭的内部.该match声明看起来是不必要的,但我无法弄清楚如何简化它.
fn example<T, E>(val: Option<Result<T, E>>) -> Result<Option<T>, E> {
Ok(match val {
Some(v) => Some(v?),
None => None
})
}
Run Code Online (Sandbox Code Playgroud) 当使用HashMap的get方法时,我得到了一个Option<&T>,这次我再次遇到它Option<&String>.我想获得自有价值Option<String>.没有我写作,这可能map(|x| x.to_owned())吗?
我只是想知道是否有办法为任何实用程序特征编写一个实现该实现的毯子实现?
trait FooTrait {}
struct FooStruct;
impl FooTrait for FooStruct {}
fn main() {
let maybe_struct: Option<FooStruct> = None;
// Does not compile, "expected trait FooTrait, found struct `FooStruct`"
// let maybe_trait: Option<Box<FooTrait>> = maybe_struct.map(Box::new);
// Compiles fine
let maybe_trait: Option<Box<FooTrait>> = match maybe_struct {
Some(s) => Some(Box::new(s)),
None => None,
};
}
Run Code Online (Sandbox Code Playgroud)
Rustc 1.23.0.为什么第一种方法不能编译?我错过了一些明显的东西,或者......嗯?
我的项目中有一个结构,该结构在逻辑上与来自不同板条箱的A结构相关。B两者内部都有一个可选的子结构 ( C/ D)。
假设对于这个例子,他们有这个结构定义:
struct D {
name: Option<String>
}
struct B {
spec: Option<D>
}
struct C {
name: Option<String>
}
struct A {
spec: Option<C>
}
Run Code Online (Sandbox Code Playgroud)
现在我想将Into-trait实现A为B:
impl Into<D> for C {
fn into(self) -> D {
D {
name: self.name
}
}
}
impl Into<B> for A {
fn into(self) -> B {
B {
spec: self.spec.into()
}
}
}
Run Code Online (Sandbox Code Playgroud)
但 Rust 不允许这样做:
error[E0277]: …Run Code Online (Sandbox Code Playgroud) 如果 RustOption提供了一些额外的便利方法,比如Option#flattenand Option#flat_map,那么这将是很好的, whereflatten会将 an 减少<Option<Option<T>>到Option<T>,并且flat_map会像 一样工作map,但采用返回 anOption并将其展平的方法/闭包。
flat_map 非常简单:
fn opt_flat_map< T, U, F: FnOnce(T) -> Option<U> >(opt: Option<T>, f: F) -> Option<U> {
match opt {
Some(x) => f(x),
None => None
}
}
Run Code Online (Sandbox Code Playgroud)
flatten更复杂,我真的不知道如何定义它。它可能看起来像:
fn opt_flatten<T, U>(opt: Option<T>) -> Option<U> {
match opt {
Some( Some(x) ) => flatten_option( Some(x) ),
_ => opt
}
}
Run Code Online (Sandbox Code Playgroud)
但这肯定行不通。有什么想法吗?
另外,我将如何在Option …