Die „nicht genügend Typinformationen über _
schließen“ Fehlermeldung in einigen anderen Fragen erläutert. Siehe Error: unable to infer enough type information about `_`; type annotations or generic parameter binding required und Unable to infer enough type information about _; type annotations or generic parameter binding required. Im Grunde bedeutet dies, dass der Compiler nicht genügend Informationen hat, um alle Typparameter in einer Funktion oder einem Datentyp anzugeben.
Dennoch, dieser spezielle Fall einige Verwirrung hervorrufen kann: warum nicht Iterator.sum()
schließt nur die Typen der resultierenden Summe an den Item
des Iterators? Durch die Addition von f64
s erwarten wir f64
als Ergebnis, oder? Nun, das Verfahren sum
ist tatsächlich wie folgt definiert:
fn sum<S>(self) -> S
where S: Sum<Self::Item>
Wo S
eine andere Art von sum
Funktion implementiert (siehe trait Sum
), die einen Iterator nimmt:
pub trait Sum<A = Self> {
fn sum<I>(iter: I) -> Self where I: Iterator<Item=A>;
}
Diese Eigenschaft gibt uns die Freiheit zu fassen Zahlen und Verweise auf gleiche Zahlen:
static MAGIC_CODE: u32 = 0xDEADBEEF;
static BLAND_CODE: u32 = 0x1234ABCD;
fn main() {
let sum1: u32 = vec![MAGIC_CODE, BLAND_CODE] // vec! infers to Vec<u32>
.into_iter().sum();
let sum2 = vec![&MAGIC_CODE, &BLAND_CODE] // vec! infers to Vec<&u32>
.into_iter().sum::<u32>();
assert_eq!(sum1, sum2);
}
Auf der anderen Seite bedeutet dies auch, dass th Die Definition einer Summe wird lockerer: Jeder andere Datentyp, der Sum<u32>
(oder Sum<&u32>
) implementiert, könnte seinen Platz in dem obigen Code einnehmen, was zu der oben erwähnten Mehrdeutigkeit führt. Für die Zwecke der Demonstration, stellt dieser Code auch:
use std::iter::Sum;
struct Accumulator(bool);
impl Sum<u32> for Accumulator {
fn sum<I: Iterator<Item = u32>>(mut iter: I) -> Self {
Accumulator(iter.any(|v| v != 0))
}
}
fn main() {
let sum3: Accumulator = {
let data = vec![MAGIC_CODE, BLAND_CODE];
data.into_iter().sum()
};
assert!(sum3.0);
}
Full code on Playground.
Die Fehlermeldung scheint klar genug zu sein: Übergeben Sie entweder das Ergebnis von 'sum()' an eine Bindung des expliziten Typs ('f64') oder fügen Sie den Typ Annotation (' sum :: () ') hinzu. Welcher Teil davon ist Ihnen weniger klar? –
Ok, ein bisschen hilfreich-aggressiv? Aber du hast einen Punkt. Der Beitrag wurde jedoch freundlicherweise bearbeitet, wobei die Fehlermeldung auf die richtige umgestellt wurde. Die Codezeilen, die ich gepostet habe, waren am Ende eines ansonsten funktionalen Skripts, aber diese Tatsache scheint die Fehlermeldung, die ich nicht erwartet hatte, verändert zu haben. –
Schau, dass ich nicht aggressiv sein wollte, aber ich habe tatsächlich deine eigene Interpretation der Fehlermeldung in deiner Frage erwartet. Ich war zu Recht neugierig, warum du es nicht verstanden hast.Eine gute Chance ist, dass Sie mehr als die Antwort benötigen, um ähnliche Probleme in der Zukunft zu überwinden. –