Comment idiomatique de la copie d'une tranche?
En Aller, la copie des tranches de série-tarif et ressemble à ceci:
# It will figure out the details to match slice sizes
dst = copy(dst[n:], src[:m])
Dans la Rouille, je ne pouvais pas trouver une méthode similaire de remplacement. Quelque chose que je suis venu avec ressemble à ceci:
fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
let mut c = 0;
for (&mut d, &s) in dst.iter_mut().zip(src.iter()) {
d = s;
c += 1;
}
c
}
Malheureusement, je reçois cette compilation d'erreur que je n'arrive pas à résoudre:
error[E0384]: re-assignment of immutable variable `d`
--> src/main.rs:4:9
|
3 | for (&mut d, &s) in dst.iter_mut().zip(src.iter()) {
| - first assignment to `d`
4 | d = s;
| ^^^^^ re-assignment of immutable variable
Comment puis-je définir d
? Est-il un meilleur moyen pour copier une tranche?
Pourriez-vous développer un peu plus sur pourquoi vous voulez copier les données dans les tranches autour? J'avais l'habitude de s'attendre à soit prendre une référence à l'original ou pour copier les données de quelque chose qui possède la copie.
OriginalL'auteur Byron | 2015-01-29
Vous devez vous connecter pour publier un commentaire.
Oui, l'utilisation de la méthode
clone_from_slice()
, il est générique sur tout type d'élément qui met en œuvreClone
.La destination
x
est un&mut [T]
tranche, ou tout ce qui derefs, comme une mutableVec<T>
vecteur. Vous devez couper la source et de destination, ainsi que leurs longueurs match.Comme de la Rouille 1.9, vous pouvez également utiliser
copy_from_slice()
. Cela fonctionne de la même manière, mais utilise leCopy
trait au lieu deClone
, et est une conséquence directe de l'emballage desmemcpy
. Le compilateur peut optimiserclone_from_slice
équivalent àcopy_from_slice
le cas échéant, mais il peut encore être utile.copy
. Dans la rouille-parler, clone peut-être le terme approprié mais ... je suis encore à m'habituer à tout cela.OriginalL'auteur
Avertissement
copy_memory
a été abandonné depuis la Rouille 1.6.0. Découvrez bluss réponse pour une solution stable.Je serais probablement utiliser
copy_memory
, qui a presque la même signature que ce que vous voulez:Noter que c'est pas une solution générique. Dans la Rouille, les tranches peuvent être de tout type, y compris ceux qui ne sont pas facilement copiable! Votre question et cette réponse, seulement affaire avec les tranches de
u8
.src.len >= dst.len
. OP version fonctionne avec des longueurs arbitraires.Mais de toute façon
copy_memory
est le chemin, car il est susceptible d'être plus efficace.bon appel! J'ai mis à jour (et ajouté mes petits tests
main
).C'est vrai, dans mon exemple, j'utilise u8, comme c'est le béton types de tranche que j'ai, et il est absolument exact que copy_memory serait le moyen le plus rapide de le faire (en supposant que le plus spécifique est la plus rapide). Ce que je cherchais était le générique de façon qu'elle soit en aller - copie() copie les tranches de n'importe quel type.
.copy_from_slice()
semble être plus approprié pour répondre à la question, alors que je serai à l'aide decopy_memory
dans mon code.copy_memory
est marqué instable, et donc inutilisable comme de la Rouille 1.1. Est-il une API stable nous devrions utiliser à la place?OriginalL'auteur
Ce code fonctionne, même si je ne suis pas sûr si c'est la meilleure façon de le faire.
Apparemment pas de définition des autorisations d'accès explicitement fait le tour. Cependant, je suis toujours confus au sujet de ce et mon modèle mental ne permet pas encore de couvrir ce qui se passe vraiment là.
Mes solutions sont pour la plupart d'essai et d'erreur quand il s'agit de ces choses, et je serais plutôt du genre à vraiment comprendre la place.
&mut d
) crée une nouvelle variable (d
dans ce cas) et l'affecte à un déréférencement de pointeur. Il n'a pas d'offrir une capacité de modifier la valeur d'origine, il ne fait que copier la valeur d'origine; si vous l'avez utilisé avec les non-Copy
type, votre programme n'a même pas compiler.BTW, vous pouvez aussi garder
&s
en place et à écrire*d = s
par la suite.OriginalL'auteur
Une autre variante serait
Notez que vous devez utiliser
count
dans ce cas, puisquelen
serait d'utiliser laExactSizeIterator
raccourci et donc de ne jamais appelernext
, résultant dans un no-op.map
ici doublement non-idomatic. Si c'est ce que vous voulez, unfor
boucle est le bon choix.J'avoue que c'est un hack, mais le
for
boucle nécessite un suivi manuel du nombre d'itérations. Au lieu demap
on pourrait sans doute utiliserinspect
pour la rendre plus claire que le "résultat" se jeter.OriginalL'auteur