(我是 Rust 新手,试图编写一个小纸牌游戏作为练习,但我可能没有正确掌握一些东西。我正在尽力解决我的问题/困惑。)
shuffle
函数。
由于
shuffle
的另一个实现并希望通过特征名称来调用它,我遇到了一个问题,我偶然发现了一些有趣但令人困惑的东西:shuffle
是由适用于 的 SliceRandom
特征实现的
[T]
(T
类型的切片),它没有为Vec<T>
实现,但Deref
特征为Vec<T>
实现,通过将
Vec<T>
强制转换为&[T]
充当桥梁, here也有说明。
fn main() {
let mut vector_deck: Vec<u32> = (1..=24).collect::<Vec<u32>>();
vector_deck.shuffle(&mut thread_rng()); // 1 works
SliceRandom::shuffle(&mut vector_deck, &mut thread_rng()); // 2 doesn't work
let mut slice_deck: &mut [u32] = vector_deck.deref_mut();
slice_deck.shuffle(&mut thread_rng()); // 3 works
SliceRandom::shuffle(slice_deck, &mut thread_rng()); // 4 works
let mut array_deck: [u32; 24] = vector_deck.try_into().unwrap();
array_deck.shuffle(&mut thread_rng()); // 5 works
SliceRandom::shuffle(&mut array_deck, &mut thread_rng()); // 6 doesn't work
}
这会导致
error[E0277]: the trait bound `Vec<u32>: SliceRandom` is not satisfied
--> src\main.rs:36:26
|
36 | SliceRandom::shuffle(&mut vector_deck, &mut thread_rng()); // 2 doesn't work
| -------------------- ^^^^^^^^^^^^^^^^ the trait `SliceRandom` is not implemented for `Vec<u32>`
| |
| required by a bound introduced by this call
|
= help: the trait `SliceRandom` is implemented for `[T]`
error[E0277]: the trait bound `[u32; 24]: SliceRandom` is not satisfied
--> src\main.rs:44:26
|
44 | SliceRandom::shuffle(&mut array_deck, &mut thread_rng()); // 6 doesn't work
| -------------------- ^^^^^^^^^^^^^^^ the trait `SliceRandom` is not implemented for `[u32; 24]`
| |
| required by a bound introduced by this call
|
= help: the trait `SliceRandom` is implemented for `[T]`
这就是困惑:
&[u32]
,但它会导致错误,所以我解引用了自己并且那么取消引用究竟是如何工作的,以及由于不存在“解决方法”(
SliceRandom::shuffle(&mut array_deck, &mut thread_rng())
),我将如何在数组上使用deref_mut()
?
可变解引用强制通常能够在每当
&mut T
时将&mut U
变成T: DerefMut<Target = U>
。通常,具有固定类型的函数调用将自行执行可变的 deref 强制转换,但在这种情况下,问题在于它是一个特征函数,因此参数的类型实际上并不知道 - 对于某些人来说这是 &mut Self
Self
实现 SliceRandom
,Rust 通常不会推断只有一个符合条件的类型满足某个特征(即 &mut Vec<T>
只能可变地解引用为 &mut [T]
,并且 [T]
实现 SliceRandom
) — 这意味着 DerefMut
没有明确的目标类型。如果一个函数显式地采用 &mut U
来表示某些固定的 U
,那么只要 &mut T
,您就可以将 T: DerefMut<Target = U>
传递给它。