web-dev-qa-db-ja.com

範囲からVecを作成してシャッフルするにはどうすればよいですか?

私は次のコードを持っています:

_extern crate Rand;

use Rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let mut slice: &[u32] = vec.as_mut_slice();

    thread_rng().shuffle(slice);
}
_

次のエラーが発生します:

_error[E0308]: mismatched types
 --> src/main.rs:9:26
  |
9 |     thread_rng().shuffle(slice);
  |                          ^^^^^ types differ in mutability
  |
  = note: expected type `&mut [_]`
             found type `&[u32]`
_

ベクトルとスライスの内容は不変であり、ここでエラーが発生することは理解できると思いますが、よくわかりません。

_as_mut_slice_のシグネチャはpub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T]であるため、スライスは変更可能でなければなりませんが、どういうわけか変更できません。

簡単な修正があるはずですが、最善を尽くしましたが、うまく機能しませんでした。

29
le_me

あなたはとても近いです。これはうまくいくはずです:

extern crate Rand;

use Rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let slice: &mut [u32] = &mut vec;

    thread_rng().shuffle(slice);
}

&mut [T]は暗黙的に&[T]に強制変換でき、slice変数に&[u32]の注釈を付けたため、スライスは不変になりました:&mut [u32]&[u32]に強制変換されました。変数のmutはここでは関係ありません。スライスは他の誰かが所有するデータを借用するだけであり、可変性を継承していないため、可変性はそのタイプでエンコードされています。

実際、sliceに対する注釈はまったく必要ありません。これも機能します:

extern crate Rand;

use Rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    let slice = vec.as_mut_slice();

    thread_rng().shuffle(slice);
}

中間変数も必要ありません。

extern crate Rand;

use Rand::{thread_rng, Rng};

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    thread_rng().shuffle(&mut vec);
}

The Rust Programming Language は、所有権と借用の概念について説明しているため、必ずお読みくださいそしてそれらが可変性とどのように相互作用するか。


更新:Rand v0.6.0以降、Rng::shuffleメソッドは廃止されました。代わりに、Rand::seq::SliceRandomトレイトを使用する必要があります。これは、すべてのスライスにshuffle()メソッドを提供し、Rngインスタンスを受け入れます。

// Rust edition 2018 no longer needs extern crate

use Rand::thread_rng;
use Rand::seq::SliceRandom;

fn main() {
    let mut vec: Vec<u32> = (0..10).collect();
    vec.shuffle(&mut thread_rng());
    println!("{:?}", vec);
}

それを見てください 遊び場で

32

次のように shuffle を使用できます。

extern crate Rand;

use Rand::Rng;

fn main() {
    let mut vec: Vec<usize> = (0..10).collect();
    println!("{:?}", vec);
    Rand::thread_rng().shuffle(&mut vec);
    println!("{:?}", vec);
}
15
Akavall