Rust中AsRef<[i32]>泛型函数使用get([1..])切片报错的原因及解决
问题
编写了一个带有AsRef<[i32]>约束的泛型参数T的函数find,希望在函数内部使用get方法传入[1..]对输入进行切片,但Rust编译器报错:the trait SliceIndex<[i32]> is not implemented for [RangeFrom<{integer}>; 1]。使用split_at方法可以正常拆分切片,使用单个索引如get(0)也能正常工作。请问无法使用该切片方式的原因是什么?是否需要添加额外的trait约束来使其生效?
代码示例:
fn find<T>(array: T, key: i32) -> Option<usize> where T: AsRef<[i32]>, { let arr = array.as_ref().get([1..]); println!("slicing successful"); None } fn main() { let arr = [1, 2, 3]; find(arr, 1); }
回答
报错原因
你这里是语法误用:[1..]会创建一个包含单个RangeFrom元素的数组,而非直接传入切片范围。get方法接收的参数是实现SliceIndex<[T]> trait的类型(比如单个usize索引、Range<usize>/RangeFrom<usize>这类范围),但数组类型[RangeFrom<usize>; 1]并没有实现该trait,因此编译器抛出错误。
解决方案
不需要添加任何额外的trait约束,只需把[1..]改成1..,直接传入RangeFrom类型的范围即可:
fn find<T>(array: T, key: i32) -> Option<usize> where T: AsRef<[i32]>, { let arr = array.as_ref().get(1..); // 移除方括号 println!("slicing successful"); None } fn main() { let arr = [1, 2, 3]; find(arr, 1); }
修改后,get(1..)会匹配SliceIndex<[i32]>的实现,编译器即可正常通过。
补充说明:
split_at(1)能正常工作,是因为它接收的参数是usize类型,和get(0)的参数类型一致,都属于合法输入;- 若要获取从索引1到末尾的切片,除了
get(1..)(越界时返回None,更安全),也可以直接用&array.as_ref()[1..],但这种方式越界会直接触发panic。
内容的提问来源于stack exchange,提问作者RamGorurerChhana
相关产品推荐
相关产品推荐

