Mas*_*ath 4 generics traits option rust
我需要一个获取实现trait Option的泛型类型的函数。一个幼稚的实现可能看起来像以下内容(是的,解包可能会引起恐慌):Tstd::iter::IntoIteratorNone
fn main() {
let v = vec![1i32, 2, 3];
print_iter(Some(v));
print_iter(None);
}
fn print_iter<T: IntoIterator<Item = i32>>(v: Option<T>) {
for e in v.unwrap() {
println!("{}", e);
}
}
Run Code Online (Sandbox Code Playgroud)
在操场上测试。
这可以按预期工作Some(...),但因以下原因而失败None:
error[E0282]: type annotations needed
--> src/main.rs:4:5
|
4 | print_iter(None);
| ^^^^^^^^^^ cannot infer type for `T`
Run Code Online (Sandbox Code Playgroud)
T在这些情况下,显然类型是未知的。一个人可以使用,print_iter::<Vec<i32>>(None);但这并不是真正的习惯,因为这提供了一些不基于任何东西的任意类型...
有什么方法可以向编译器暗示我不在乎None或使用某种默认值吗?
有什么方法可以向编译器暗示我不在乎
None或使用某种默认值吗?
您可以实现自己的非通用值作为默认值。对于初学者,我们假设print_iter不接受Option<T>,而是一个自己的枚举:
enum PrintArg<T> {
Ignore,
Use(T),
}
fn print_iter<T: IntoIterator<Item = i32>>(v: PrintArg<T>) {
if let PrintArg::Use(v) = v {
for e in v {
println!("{}", e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这还不能解决问题,因为如果传递PrintArg::Ignore给print_iter(),您回到第一个平方-编译器无法推断T。但是使用您自己的类型,您可以轻松地更改print_iter为接受可以转换 为 PrintArg以下内容的任何内容:
fn print_iter<T, V>(v: T)
where
T: Into<PrintArg<V>>,
V: IntoIterator<Item = i32>,
{
if let PrintArg::Use(v) = v.into() {
for e in v {
println!("{}", e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
进行此修改后,您可以创建一个虚拟非泛型Ignore值,并使用该From特征将其转换为您选择的PrintArg::Ignore<T>with T,例如:
struct Ignore;
impl From<Ignore> for PrintArg<Vec<i32>> {
fn from(_v: Ignore) -> Self {
PrintArg::Ignore
}
}
Run Code Online (Sandbox Code Playgroud)
与Ignore非泛型一样,其使用不需要(或接受)<T>。尽管我们确实必须PrintArg<T>在Fromtrait实现中发明一种类型,但我们从不构造它,因此,只要满足IntoIterator边界,我们选择哪种类型就无关紧要。
当然,你还是会希望能够调用print_iter()用Some(...),所以你也需要定义的转换Option<T>到PrintArg<T>:
impl<T> From<Option<T>> for PrintArg<T> {
fn from(v: Option<T>) -> Self {
match v {
Some(v) => PrintArg::Use(v),
None => PrintArg::Ignore,
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了这些之后,您的API就变得干净了,main()看起来像这样(操场):
fn main() {
let v = vec![1i32, 2, 3];
print_iter(Some(v));
print_iter(Ignore);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |