类型&[u8]无法用usize索引?Rust编译错误求助
问题:传递
&[u8]引用给泛型函数时触发Index trait编译错误 因为不想调用seqs.to_owned()产生额外开销,直接将&[u8]类型的引用传入reverse_complement_seq_u8函数,却遇到了编译错误,以下是相关代码和错误信息:
测试代码
pub fn reverse_complement_seq_u8<T>(seq: T, len: usize) -> Vec<u8> where T: std::ops::Index<usize, Output = u8> { (0..len).rev().map(|i| match seq[i] { 65 | 97 => 84, // 'A' | 'a' => 'T' 84 | 116 => 65, // 'T' | 't' => 'A' 71 | 103 => 67, // 'G' | 'g' => 'C' 67 | 99 => 71, // 'C' | 'c' => 'G' n => n, } ).collect() } fn main() { let seqs = "ACGATGCTACGA".as_bytes();//generated by another function let revcom_seq = reverse_complement_seq_u8(seqs, seqs.len()); println!("{:?}", revcom_seq); }
编译错误信息
error[E0277]: the type `&[u8]` cannot be indexed by `usize` --> src/main.rs:17:48 | 17 | let revcom_seq = reverse_complement_seq_u8(seqs, seqs.len()); | ------------------------- ^^^^ `&[u8]` cannot be indexed by `usize` | | | required by a bound introduced by this call | = help: the trait `Index<usize>` is not implemented for `&[u8]` = help: the following other types implement trait `Index<Idx>`: [T; N] [T] note: required by a bound in `reverse_complement_seq_u8`
解决办法
方法一:修改泛型约束支持可解引用类型
原约束要求T直接实现Index<usize>,但&[u8]是[u8]的引用,需要先解引用才能使用索引。调整约束让T支持解引用到实现Index<usize>的类型:
pub fn reverse_complement_seq_u8<T>(seq: T, len: usize) -> Vec<u8> where T: std::ops::Deref, <T as std::ops::Deref>::Target: std::ops::Index<usize, Output = u8>, { (0..len).rev().map(|i| match seq.deref()[i] { b'A' | b'a' => b'T', b'T' | b't' => b'A', b'G' | b'g' => b'C', b'C' | b'c' => b'G', n => n, } ).collect() }
方法二:改用AsRef<[u8]>约束(推荐)
AsRef<[u8]>是更通用的约束,&[u8]、[u8]、String等类型都实现了该trait,同时用迭代器替代手动索引,代码更简洁安全:
pub fn reverse_complement_seq_u8<T: AsRef<[u8]>>(seq: T, len: usize) -> Vec<u8> { seq.as_ref() .iter() .take(len) .rev() .map(|&c| match c { b'A' | b'a' => b'T', b'T' | b't' => b'A', b'G' | b'g' => b'C', b'C' | b'c' => b'G', n => n, }) .collect() }
修改后直接传递seqs(&[u8]类型)即可正常编译运行,且无额外内存开销。
方法三:调用时手动解引用
如果不想修改函数代码,可以在调用时对&[u8]解引用后再传引用:
let revcom_seq = reverse_complement_seq_u8(&*seqs, seqs.len());
这种方式能解决问题,但不够优雅,通用性不如前两种方法。
内容的提问来源于stack exchange,提问作者Moold
相关产品推荐
相关产品推荐

