对迭代器进行分区时,没有为 Vec 实现 trait Extend [英] The trait Extend is not implemented for Vec when partitioning an iterator

查看:25
本文介绍了对迭代器进行分区时,没有为 Vec 实现 trait Extend的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在向量迭代器上调用 .partition() 时遇到错误:

I am running into the error when calling .partition() on a vector iterator:

error[E0277]: the trait bound `std::vec::Vec<std::result::Result<std::collections::HashSet<&std::string::String>, std::boxed::Box<dyn std::error::Error>>>: std::iter::Extend<&std::result::Result<std::collections::HashSet<std::string::String>, std::boxed::Box<dyn std::error::Error>>>` is not satisfied
 --> src/main.rs:9:24
  |
9 |         results.iter().partition(|r| r.is_ok());
  |                        ^^^^^^^^^ the trait `std::iter::Extend<&std::result::Result<std::collections::HashSet<std::string::String>, std::boxed::Box<dyn std::error::Error>>>` is not implemented for `std::vec::Vec<std::result::Result<std::collections::HashSet<&std::string::String>, std::boxed::Box<dyn std::error::Error>>>`
  |
  = help: the following implementations were found:
            <std::vec::Vec<T> as std::iter::Extend<&'a T>>
            <std::vec::Vec<T> as std::iter::Extend<T>>

运行以下代码时:

use std::collections::HashSet;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

fn main() {
    let mut results: Vec<Result<HashSet<String>>> = Default::default();

    let (okays, errors): (Vec<Result<HashSet<&String>>>, Vec<_>) =
        results.iter().partition(|r| r.is_ok());
}

参见 playground例如.

推荐答案

如错误消息所述(移除命名空间):

As the error message states (with namespacing removed):

特征 Extend<&Result, Box>> 未为 Vec 实现,Box>>

您不能使用 &T 类型的元素扩展 Vec,因为它们不是同一类型.

You can't extend a Vec<T> with elements of type &T because they aren't the same type.

相反,您可以执行以下操作之一:

Instead, you can do one of these:

  1. 将目标集合的类型更改为 Vec<&Result>>(或只是 Vec<_>,就像你的第二个目标类型一样,允许编译器推断内部类型).

  1. Change the type of the destination collection to Vec<&Result<HashSet<String>>> (or just Vec<_>, like your second destination type, to allow the compiler to infer the inner type).

将引用转换为拥有的值,可能通过 cloneto_owned.

Convert the reference to an owned value, perhaps via clone or to_owned.

不要在开始时迭代引用,而是使用 into_iterdrain.

Don't iterate over references to start with, using into_iter or drain instead.

但是,您当前的类型将很难实现或成本很高,因为您声明您想要一个拥有的 Result 和一个拥有的 HashMap 但一个 reference String.

However, your current type will be very hard or expensive to achieve, as you state that you want an owned Result with an owned HashMap but a reference the String.

我认为最好的方法是使用 Itertools::partition_mapinto_iter:

I think the best thing is to use Itertools::partition_map and into_iter:

use itertools::Itertools; // 0.9.0
use std::collections::HashSet;

type Error = Box<dyn std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;

fn main() {
    let mut results: Vec<Result<HashSet<String>>> = Default::default();

    let (errors, okays): (Vec<_>, Vec<_>) = results.into_iter().partition_map(Into::into);
    // let (errors, okays): (Vec<Error>, Vec<HashSet<String>>)
}

另见:

这篇关于对迭代器进行分区时,没有为 Vec 实现 trait Extend的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆