web-dev-qa-db-ja.com

スライスを慣用的にコピーする方法は?

Goでは、スライスのコピーは標準的な料金で、次のようになります。

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

Rustでは、置換として同様の方法を見つけることができませんでした。私が思いついたものは次のようになります:

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
}

残念ながら、解決できないこのコンパイルエラーが発生します。

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

dを設定するにはどうすればよいですか?スライスをコピーするより良い方法はありますか?

24
Byron

はい、メソッド clone_from_slice() を使用します。これは、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]
}
_

宛先xは、_&mut [T]_スライス、または可変_Vec<T>_ベクトルのようにそれを間接参照するもののいずれかです。長さが一致するように、宛先とソースをスライスする必要があります。


Rust 1.9では、 copy_from_slice() も使用できます。これは同じように機能しますが、代わりにCopy特性を使用しますCloneであり、memcpyの直接ラッパーです。コンパイラは_clone_from_slice_を最適化して_copy_from_slice_と同等にできますが、それでも有用です。

33
bluss

最適な方法かどうかはわかりませんが、このコードは機能します。

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 
}

どうやらアクセス許可を明示的に指定しないことがトリックを実行したようです。しかし、私はまだこれについて混乱しており、私の精神モデルはまだそこで起こっていることをカバーしていません。私のソリューションは、これらのことに関してはほとんど試行錯誤であり、代わりに真に理解したいと思います。

2
Byron