2015-04-09 10 views
19

This Rust tutorial spiega il meccanismo fold() bene, e questo codice di esempio:Come faccio a sommare un vettore usando la piega?

let sum = (1..4).fold(0, |sum, x| sum + x); 

funziona come previsto.

mi piacerebbe eseguirlo su un vettore, in modo sulla base di tale esempio, prima ho scritto questo:

let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, val| sum += val); 

che gettò un errore:

error: binary assignment operation `+=` cannot be applied to types `_` and `&u32` [E0368] 
let sum = ratings.values().fold(0, |sum, val| sum += val); 
               ^~~~~~~~~~ 

ho indovinato che questo potrebbe essere un errore di riferimento connessi per qualche ragione, così cambiato che a fold(0, |sum, &val| sum += val), che ha portato con

error: mismatched types: 
expected `u32`, 
    found `()` 

Hm, forse qualcosa non va con la chiusura? Usando {sum += x; sum }, ho ottenuto

binary assignment operation `+=` cannot be applied to types `_` and `&u32` 

di nuovo.

Dopo ulteriori prove ed errori, aggiungendo mut-sum lavorato:

let sum = vec![1,2,3,4,5,6].iter().fold(0, |mut sum, &x| {sum += x; sum}); 

Qualcuno potrebbe spiegare il motivo per cui fold() per i vettori differisce tanto dal tutorial? O c'è un modo migliore per gestire questo?

Per riferimento, sto utilizzando Rust beta, 2015-04-02.

+7

ti ha introdotto una grande differenza sostituendo 'somma + x' da' sum + = x' . – Levans

+0

Non ci posso credere, come potrei mancarmi ... Grazie! – mmatyas

risposta

24

Hai già capito che il problema è +=, ma mi piacerebbe fornire un po 'più di esposizione.

Nel tuo caso, gli argomenti forniti per la chiusura fold sono _ e &u32. Il primo tipo è un numero intero non ancora specificato. Se si cambia la chiamata piega a fold(0u32, |sum, val| sum += val), si otterrà un messaggio leggermente diverso:

let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0u32, |sum, val| sum += val); 
error[E0308]: mismatched types 
    | 
2 |  let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0u32, |sum, val| sum += val); 
    |                   ^^^ expected u32, found &{integer} 
    | 
    = note: expected type `u32` 
    = note: found type `&{integer}` 

Il valore del risultato dell'operazione di assegnazione binaria += è (), il tipo di unità.Questo spiega il messaggio di errore quando si è modificato a fold(0, |sum, &val| sum += val):

let mut a = 1; 
let what_am_i = a += 1; 
println!("{:?}", what_am_i); // =>() 

Se si passa a fold(0, |sum, &val| {sum += val ; sum}), allora ottiene un errore comprensibile sulle variabili immutabili:

let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, &val| {sum += val; sum}); 
error[E0384]: re-assignment of immutable variable `sum` 
--> src/main.rs:2:66 
    | 
2 |  let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, &val| {sum += val; sum}); 
    |              ---   ^^^^^^^^^^ re-assignment of immutable variable 
    |              | 
    |              first assignment to `sum` 

Da qui, si potrebbe contrassegno sum come mutabile, ma la soluzione corretta è semplicemente piegare con , come hai scoperto.


Nelle versioni più recenti di Rust, si può anche solo sum l'iteratore direttamente, saltando fold:

let sum: u32 = vec![1,2,3,4,5,6].iter().sum(); 
7

quindi si è rivelato c'era una differenza enorme nel mio codice, come ho scritto

sum += x

invece di

sum + x.

Beh, almeno spero che questa domanda aiuti, nel caso in cui qualcuno si trova in una situazione simile.

Problemi correlati