以下是测试代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
因为调用seqs.to_owend()成本很高,所以我只想将其引用传递给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);
}
Run Code Online (Sandbox Code Playgroud)
问题在于,虽然切片本身[u8]可以被索引,但对切片的引用&[u8]却不能。大多数情况下,对切片引用进行索引是有效的,因为 Rust 会根据需要自动取消引用,但在使用泛型时,您需要更加严格地告诉编译器。
seq: &T一种可能的解决方法是在参数中使用,以便可以T对[u8]which 进行索引。这需要一个额外的+ ?Sized边界,否则编译器会添加一个Sized切片不实现的隐式边界:
pub fn reverse_complement_seq_u8<T>(seq: &T, len: usize) -> Vec<u8>
where
T: std::ops::Index<usize, Output = u8> + ?Sized,
{
(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);
}
Run Code Online (Sandbox Code Playgroud)
也适用于装箱切片的另一个选项是指定T必须取消引用某些可索引类型:
use std::ops::Deref;
pub fn reverse_complement_seq_u8<T, U>(seq: T, len: usize) -> Vec<u8>
where
T: Deref<Target = U>,
U: std::ops::Index<usize, Output = u8> + ?Sized,
{
(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);
}
Run Code Online (Sandbox Code Playgroud)