Rust中Trait、切片与数组的解引用及shuffle调用问题
问题解答
1. 为什么方法调用能自动解引用,Trait关联函数不行?
Rust的方法调用语法(obj.method())有一套特殊的自动解引用查找逻辑:当你调用一个方法时,编译器会自动尝试对obj进行解引用(包括Deref/DerefMut强制转换),直到找到某个类型上实现了该方法。比如Vec<T>调用shuffle时,编译器会自动把&mut Vec<T>解引用成&mut [T],而[T]正好实现了SliceRandom trait的shuffle方法,所以能正常工作。
但直接调用Trait关联函数(SliceRandom::shuffle(&mut obj, ...))时,编译器不会做这个自动解引用操作——它只会严格检查传入的第一个参数(也就是self对应的参数)是否直接实现了SliceRandom trait。Vec<T>和数组[T; N]都没有直接实现SliceRandom,只有切片[T]实现了,所以直接传&mut Vec<T>或&mut [T; N]会报错。
2. 如何通过SliceRandom::shuffle正确打乱数组?
数组虽然没有DerefMut,但可以直接强制转换为可变切片,有两种常用方式:
方式一:使用切片范围语法
把数组转换成&mut [T]切片后传入:
use rand::Rng; use rand::seq::SliceRandom; fn main() { let mut rng = rand::thread_rng(); let mut array_deck = [1, 2, 3, 4, 5]; // 把数组转换成可变切片 SliceRandom::shuffle(&mut array_deck[..], &mut rng); println!("{:?}", array_deck); }
方式二:使用数组的as_mut_slice方法
数组类型自带as_mut_slice方法,直接生成可变切片:
use rand::Rng; use rand::seq::SliceRandom; fn main() { let mut rng = rand::thread_rng(); let mut array_deck = [1, 2, 3, 4, 5]; SliceRandom::shuffle(array_deck.as_mut_slice(), &mut rng); println!("{:?}", array_deck); }
这两种方式本质都是把数组转换成&mut [T],而[T]实现了SliceRandom,所以就能正常调用shuffle关联函数了。
内容的提问来源于stack exchange,提问作者Don
相关产品推荐
相关产品推荐

