Comment puis-je additionner un vecteur en utilisant fold?
Ce tutoriel Rust explique bien le mécanisme fold()
, et cet exemple de code:
let sum = (1..4).fold(0, |sum, x| sum + x);
Fonctionne comme prévu.
Je voudrais l'exécuter sur un vecteur, donc sur la base de cet exemple, j'ai d'abord écrit ceci:
let sum: u32 = vec![1,2,3,4,5,6].iter().fold(0, |sum, val| sum += val);
, Qui a jeté une erreur:
error: binary assignment operation `+=` cannot be applied to types `_` and `&u32` [E0368]
let sum = ratings.values().fold(0, |sum, val| sum += val);
^~~~~~~~~~
J'ai deviné que cela pourrait être une erreur liée à la référence pour une raison quelconque, donc j'ai changé cela en fold(0, |sum, &val| sum += val)
, ce qui a abouti à
error: mismatched types:
expected `u32`,
found `()`
Hm, peut-être que quelque chose ne va pas avec la fermeture? En Utilisant {sum += x; sum }
, Je got
binary assignment operation `+=` cannot be applied to types `_` and `&u32`
Encore.
Après d'autres essais et erreurs, ajouter mut
à sum
travaillé:
let sum = vec![1,2,3,4,5,6].iter().fold(0, |mut sum, &x| {sum += x; sum});
Quelqu'un pourrait-il expliquer pourquoi fold()
pour les vecteurs diffère tellement du tutoriel? Ou est-il une meilleure façon de gérer cela?
Pour référence, j'utilise Rust beta, 2015-04-02.
2 réponses
Vous avez déjà compris que +=
est le problème, mais je voudrais fournir plus d'exposition.
, Dans votre cas, les arguments fournis à la fold
fermeture sont _
et &u32
. Le premier type est un entier non encore spécifié. Si vous changez votre appel fold à fold(0u32, |sum, val| sum += val)
, vous obtiendrez un message légèrement différent:
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}`
La valeur de résultat de l'opération d'affectation binaire +=
est ()
, le type d'unité. Ceci explique le message d'erreur lorsque vous avez changé pour fold(0, |sum, &val| sum += val)
:
let mut a = 1;
let what_am_i = a += 1;
println!("{:?}", what_am_i); // => ()
Si vous changez pour fold(0, |sum, &val| {sum += val ; sum})
, Vous obtenez alors une erreur compréhensible sur les variables immuables:
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`
À partir de là, vous pourriez marquer {[15] } comme mutable, mais la solution correcte est de simplement plier avec sum + val
, comme vous l'avez découvert.
Dans les nouvelles versions de Rust, vous pouvez également sum
l'itérateur directement, en sautant fold
:
let sum: u32 = vec![1,2,3,4,5,6].iter().sum();
Il s'est donc avéré qu'il y avait une énorme différence dans mon code, comme je l'ai écrit
sum += x
Au Lieu de
sum + x
.
Eh bien, au moins j'espère que cette question Aide, au cas où quelqu'un se retrouverait dans une situation similaire.