我正试图构建一个特征(ByteArray),它抽象出拥有的序列与borrow 的序列.例如,它将允许我执行以下操作:

struct Container<T:ByteArray> {
   data: T
}

然后我可以实例化Container<Vec<u8>>(它拥有数据的地方)和Container<&[u8]>(它不拥有数据的地方).我的方法是:

use std::ops;

pub trait ByteArray : ops::Index<usize,Output=u8> {
    fn len(&self) -> usize;
}

impl ByteArray for Vec<u8> {
    fn len(&self) -> usize { self.len() }
}

impl<'a> ByteArray for &'a [u8] {
    fn len(&self) -> usize { self.len() }
}

从逻辑上讲,这在我看来是合理的.但是,它失败了,错误如下:

 `&'a [u8]` cannot be indexed by `usize`

所以,我对此感到困惑.我知道我可以为[u8]实现ByteArray,但这不符合我上面的用例.似乎我也可以通过引入一个中介特性来解决这个问题,如下所示:

pub struct ArraySlice<'a,T>(&'a [T]);

impl<'a,T> ops::Index<usize> for ArraySlice<'a,T> {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        &self[index]
    }
}

impl<'a> ByteArray for ArraySlice<'a,u8> {
    fn len(&self) -> usize {
        self.len()
    }
}

但是,这对我来说有点老生常谈,我假设有更好的解决方案.如有任何意见,敬请垂询!

推荐答案

您可以使用Deref:

pub trait ByteArray 
where
    Self: ops::Deref,
    <Self as ops::Deref>::Target: ops::Index<usize, Output = u8>,
{
    fn len(&self) -> usize;
}

playground

Rust相关问答推荐

为什么对不可复制数据的引用的取消引用没有O权限来避免Rust中的双重释放?

在自身功能上实现类似移动的行为,以允许通过大小的所有者进行呼叫(&;mut;self)?

关于如何初始化弱 struct 字段的语法问题

如何在Rust中将选项<;选项<;字符串>;转换为选项<;选项&;str>;?

Rust ndarray:如何从索引中 Select 数组的行

装箱特性如何影响传递给它的参数的生命周期 ?(举一个非常具体的例子)

在 Rust 中,在需要引用 self 的 struct 体方法中使用闭包作为 while 循环条件

为什么 GAT、生命周期和异步的这种组合需要 `T: 'static`?

找不到 .has_func 或 .get_func 的 def

如何对一个特征的两个实现进行单元测试?

我可以解构self 参数吗?

如何将一个矩阵的列分配给另一个矩阵,纳尔代数?

在多核嵌入式 Rust 中,我可以使用静态 mut 进行单向数据共享吗?

为什么 Rust 的临时值有时有参考性有时没有?

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

无法把握借来的价值不够长寿,请解释

如何用另一个变量向量置换 rust simd 向量?

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?

当值是新类型包装器时,对键的奇怪 HashMap 生命周期要求

返回 &str 但不是 String 时,borrow 时间比预期长