gpt4 book ai didi

rust - 类型 `&[u8]` 不能被 `usize` 索引?

转载 作者:行者123 更新时间:2023-12-05 08:44:54 25 4
gpt4 key购买 nike

下面是测试代码:

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);
}

因为调用 seqs.to_owend() 很昂贵,所以我只想将它的引用传递给 reverse_complement_seq_u8,但是这会导致以下错误:

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`

最佳答案

问题在于,虽然切片本身 [u8] 可以被索引,但对切片 &[u8] 的引用不能。大多数时候,索引切片引用是有效的,因为 Rust 会根据需要自动解除引用,但是当使用泛型时,您需要更严格地告诉编译器。

一个可能的解决方法是在参数中使用seq: &T 这样T 将是可以索引的[u8]。这需要一个额外的 + ?Sized 绑定(bind),否则编译器会添加一个隐式的 Sized 绑定(bind),而切片不会实现:

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);
}

Playground

另一个也适用于盒装切片的选项是指定 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);
}

Playground

关于rust - 类型 `&[u8]` 不能被 `usize` 索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74848949/

25 4 0