是否可以创建一个接受<string> Option 或 Option<&str> 作为 Rust 参数的函数?



是否可以在 Rust 中创建一个接受Option<String>Option<&str>作为参数的函数? 这是我的测试,但编译器报告错误。

#![allow(unused_variables)]
#![allow(dead_code)]
struct Person {
name: String,
}
impl Person {
fn new<S: Into<Option<String>>>(name: S) -> Person {
Person { name: name.into().unwrap_or("unknown".to_string()) }
}
}
fn main() {
let person1 = Person::new(Some("Test"));
let person2 = Person::new(Some("Test".to_string()));
}

我认为你想得到一个Option,但有不同的内在类型。函数签名应反映:

fn new<S: ToString>(name: Option<S>) -> Person {}

我将泛型类型从Into<String>更改为ToStringToString因为"对于实现显示特征的任何类型自动实现",并且您的函数可以接受更多不同的类型。

由于有Option我将进行如下操作:

Option的内部类型 (S) 转换为String

name.map(|name| name.to_string()

使用默认值解开选项的包装

.unwrap_or_else(|| "unknown".to_string())

我使用unwrap_or_else而不是unwrap_or,因为即使OptionSomeunwrap_or调用函数to_string,但只有在OptionNone时才unwrap_or_else

完整代码:

fn new<S: ToString>(name: Option<S>) -> Person {
Person {
name: name
.map(|name| name.to_string())
.unwrap_or_else(|| "unknown".to_string()),
}
}
这是我

的测试,但编译器报告错误。

提醒:Rust 的编译器是一个相当有帮助的家伙,当它抱怨阅读错误是有用的,当你寻求帮助时,发布这些错误对读者也很有用。

这里的错误相当明显:

error[E0277]: the trait bound `Option<String>: From<Option<&str>>` is not satisfied
--> src/main.rs:14:31
|
14 |     let person1 = Person::new(Some("Test"));
|                   ----------- ^^^^^^^^^^^^ the trait `From<Option<&str>>` is not implemented for `Option<String>`
|                   |
|                   required by a bound introduced by this call
|
= help: the following implementations were found:
<Option<&'a T> as From<&'a Option<T>>>
<Option<&'a mut T> as From<&'a mut Option<T>>>
<Option<T> as From<T>>

这意味着没有Option->Option通过From/Into实现,所以这是一个死胡同。

但是由于Option是一个具体的类型,你实际上不需要从Option<A>Option<B>的"内置"转换,相反,你可以只使用Option::map并调用现有的A -> B转换函数:

Person { name: name.map(Into::into).unwrap_or("unknown".to_string()) }

顺便说一下,有一种类型几乎是为此制作的(不是Option位,而是"可能是字符串或引用Cow

顺便说一下:a.unwrap_or(b.to_string())是相当糟糕的风格(clippy警告不要这样做):因为Rust是一种渴望的语言,所以它总是会分配一个字符串,即使在已经有一个字符串的情况下也是如此。

最新更新