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

标签 rust

下面是测试代码:

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/

相关文章:

rust - 如何将两个同名的 header 附加到 Warp `Reply` ?

gdb - 如何遍历 GDB 或 LLDB 中的 Rust 枚举字段?

rust - 使用 HRTB 自动化 getter 方法单元测试

rust - Rust LinkedList 中的借用检查器错误的原因是什么?

rust - 为什么使用 rustc 命令构建看不到 crate?

rust - 没有为类型 Option<&std::ffi::OsStr> 找到名为 to_str 的方法?

rust - 是否可以选择让 rustc 显示 "successful"消息?

rust - 为 Rust 的 hyper http crate 使用自定义传输器

string - 将 char 转换为 &str

rust - 如何将元素从盒装切片中移出,在此过程中消耗切片?