如何编写一个知道实现者是 [u8] 的特征方法?

Joh*_*ove 1 rust

我正在实现一个特征&[u8],但无法self在特征实现中使用。我假设该特征无法检测类型,我应该使用一个where子句,但我不知道如何在没有实现者的情况下使用它。

use std::fmt::Debug;

pub trait Xor: Debug {
    fn xor(&self, key_bytes: &[u8]) -> &[u8] {
        for n in &self[..] {
            dbg!(n);
        }
        unimplemented!()
    }
}

impl Xor for [u8] {}

fn main() {
    let xa = b"1234";
    xa.xor(b"123");
}
Run Code Online (Sandbox Code Playgroud)

操场

use std::fmt::Debug;

pub trait Xor: Debug {
    fn xor(&self, key_bytes: &[u8]) -> &[u8] {
        for n in &self[..] {
            dbg!(n);
        }
        unimplemented!()
    }
}

impl Xor for [u8] {}

fn main() {
    let xa = b"1234";
    xa.xor(b"123");
}
Run Code Online (Sandbox Code Playgroud)

tre*_*tcl 5

您可以在两个地方编写特征方法的主体:

  • 在特征本身内部,作为提供的方法
  • 在一个impl块内。

如果未提供方法,则该方法是必需的,这意味着所有实现者都必须在适当的块中编写自己的方法体impl

提供的方法只能使用该特征的所有实现者所共有的属性,这意味着您只能使用其他特征方法或超级特征的方法(例如: Debug)。但是impl块中的方法可以使用特定于实现特征的类型的属性。你想使用特定于[u8]-- 索引通过[..]-- 的东西,所以xor应该是一个必需的方法:

pub trait Xor {
    fn xor(&self, key_bytes: &[u8]) -> &[u8];
}

impl Xor for [u8] {
    fn xor(&self, key_bytes: &[u8]) -> &[u8] {
        for n in &self[..] {
            dbg!(n);
        }
        unimplemented!()
    }
}
Run Code Online (Sandbox Code Playgroud)

提供的方法通常是为了方便起见,只使用具有相同特征的其他方法,就像大多数方法一样Iterator(请参阅为什么我们不实现 Iterator 中的所有函数来实现迭代器?)。

是否可以实现多种类型的特征[无需编写多个impl块]?

是的,如果有一个特征公开了您将用来编写的功能Xor,您可以使用该特征来编写通用的impl. 例如,String[u8]都实现AsRef<[u8]>,因此您可以使用它来编写impl适用于两者的 :

impl<T: ?Sized + AsRef<[u8]>> Xor for T {
    fn xor(&self, key_bytes: &[u8]) -> &[u8] {
        for n in &self.as_ref()[..] {
            dbg!(n);
        }
        unimplemented!()
    }
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接。

也可以看看