Das Merkmal Extend wird für Vec beim Partitionieren eines Iterators nicht implementiert

Aug 26 2020

Beim Aufrufen .partition()eines Vektoriterators tritt der Fehler auf:

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>>

Beim Ausführen des folgenden Codes:

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());
}

Siehe zum Beispiel Spielplatz .

Antworten

1 Shepmaster Aug 26 2020 at 17:01

Wie in der Fehlermeldung angegeben (mit entferntem Namespace):

Das Merkmal Extend<&Result<HashSet<String>, Box<dyn Error>>>ist nicht implementiert fürVec<Result<HashSet<&String>, Box<dyn Error>>>

Sie können a nicht Vec<T>mit Elementen des Typs erweitern, &Tda diese nicht vom selben Typ sind .

Stattdessen können Sie eine der folgenden Aktionen ausführen:

  1. Ändern Sie den Typ der Zielsammlung in Vec<&Result<HashSet<String>>>(oder genau Vec<_>wie Ihren zweiten Zieltyp, damit der Compiler auf den inneren Typ schließen kann).

  2. Konvertieren Sie den Verweis in einen eigenen Wert, möglicherweise über cloneoder to_owned.

  3. Iterieren Sie zunächst nicht über Referenzen, verwenden Sie stattdessen into_iteroder drain.

Ihr aktueller Typ wird jedoch sehr schwer oder teuer zu erreichen sein, da Sie angeben, dass Sie einen Eigentümer Resultmit einem Eigentümer, HashMapaber einer Referenz der möchten String.

Ich denke, das Beste ist zu verwenden Itertools::partition_mapund 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>>)
}

Siehe auch:

  • Was ist der Unterschied zwischen iter und into_iter?