web-dev-qa-db-fra.com

Comment copier idiomatiquement une tranche?

Dans Go, la copie de tranches est au tarif standard et ressemble à ceci:

# It will figure out the details to match slice sizes
dst = copy(dst[n:], src[:m])

À Rust, je n'ai pas trouvé de méthode similaire au remplacement. Quelque chose que j'ai trouvé 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, j'obtiens cette erreur de compilation que je ne peux 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? Existe-t-il un meilleur moyen de copier une tranche?

24
Byron

Oui, utilisez la méthode clone_from_slice() , elle est générique sur tout type d'élément qui implémente Clone.

fn main() {
    let mut x = vec![0; 8];
    let y = [1, 2, 3];
    x[..3].clone_from_slice(&y);
    println!("{:?}", x);
    // Output:
    // [1, 2, 3, 0, 0, 0, 0, 0]
}

La destination x est soit une tranche &mut [T], Soit tout ce qui y dérive, comme un vecteur Vec<T> Mutable. Vous devez découper la destination et la source afin que leurs longueurs correspondent.


À partir de Rust 1.9, vous pouvez également utiliser copy_from_slice() . Cela fonctionne de la même manière mais utilise le trait Copy au lieu de Clone, et est un wrapper direct de memcpy. Le compilateur peut optimiser clone_from_slice pour être équivalent à copy_from_slice le cas échéant, mais il peut toujours être utile.

33
bluss

Ce code fonctionne, même si je ne suis pas sûr que ce soit la meilleure façon de le faire.

fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
    let mut c = 0;
    for (d, s) in dst.iter_mut().Zip(src.iter()) {
        *d = *s;
        c += 1;
    }
    c 
}

Apparemment, ne pas spécifier explicitement les autorisations d'accès a fait l'affaire. Cependant, je suis toujours confus à ce sujet et mon modèle mental ne couvre pas encore ce qui se passe vraiment là-bas. Mes solutions sont principalement des essais et des erreurs en ce qui concerne ces choses, et je préfère plutôt vraiment comprendre.

2
Byron