【问题标题】:How do I create a Vec from a range and shuffle it?如何从一个范围创建一个 Vec 并将其洗牌?
【发布时间】:2025-12-30 18:05:06
【问题描述】:

我有以下代码:

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&lt;'a&gt;(&amp;'a mut self) -&gt; &amp;'a mut [T],所以切片应该是可变的,但不知何故它不是。

我知道必须有一个简单的解决方法,但我尽了最大努力却无法让它发挥作用。

【问题讨论】:

    标签: iterator immutability rust mutability


    【解决方案1】:

    兰德 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);
    }
    

    on Playground

    原答案

    你很亲密。这应该有效:

    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);
    }
    

    &amp;mut [T] 隐式强制转换为&amp;[T],并且您使用&amp;[u32] 注释了slice 变量,因此切片变得不可变:&amp;mut [u32] 被强制转换为&amp;[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,因为它解释了所有权和借用的概念以及它们如何与可变性相互作用。


    【讨论】:

    • 感谢您的回答。不幸的是,我将您的代码粘贴到 Rust Playground (play.rust-lang.org) 并发现 thread_rng().shuffle 现在已弃用。你知道我们现在应该如何洗牌一个向量吗? (我认为我们应该使用 trait,但我在 Rust 方面的经验还不够,不知道如何做到这一点。)
    【解决方案2】:

    你可以像这样使用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);
    }
    

    【讨论】:

    • 感谢您的回答。不幸的是,我将您的代码粘贴到 Rust Playground (play.rust-lang.org) 中,发现 thread_rng().shuffle 现在已被弃用。你知道我们现在应该如何洗牌一个向量吗? (我认为我们应该使用 trait,但我在 Rust 方面的经验还不够,不知道如何做到这一点。)
    • @J-L,我明白了。谢谢。我试着用另一种方式来做:play.rust-lang.org/…,但我收到了不同的警告,不确定这是否是一个更好的解决方案。
    最近更新 更多