From Trait - 如何从切片实现它

use*_*502 2 rust

查看Traitstd::convert::From的文档,它说:

用于在消耗输入值时进行值到值的转换。

对我来说,看看fn from(T) -> Self签名,听起来该函数拥有参数的所有权。

例如如何String实现该From<&str>特征?它不能从共享引用中获取所有权。

我想实现一个“查看器”结构;不拥有所有权的东西:假设 a&[u8]代表我的二进制数据;第一个字节是我的“数据ID”。

struct DataView {
    id: u8,
    data: &[u8],
}
Run Code Online (Sandbox Code Playgroud)

然后我希望能够做类似的事情:

impl From<&[u8]> for DataView {
    fn from(buffer: &[u8]) -> DataView {
        DataView {
            id: buffer[0],
            data: &buffer[1..],
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样的事情可能吗?如果我只对“观看”感兴趣,这样的结构有意义吗?

Ada*_*dam 5

是的,您可以在不取得所有权的情况下做到这一点。但首先,每个包含引用的结构都需要一个生命周期来断言,它在其引用的数据范围内不存在:

#[derive(Debug)]
struct DataView<'a> {
    id: u8,
    data: &'a [u8],
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以通过以下方式实现 From 特征:

impl<'a> From<&'a [u8]> for DataView<'a> {
    fn from(arg: &'a [u8]) -> Self {
        let id = arg[0];
        let data = &arg[1..];
        Self { id, data }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们明确断言引用的参数与 DataView 对象具有相同的生命周期。现在我们可以这样做:

fn main() {
    let arg: &[u8] = &[1, 2, 3, 4, 6];

    let view = DataView::from(arg);
    println!("{:?}", view);
}
Run Code Online (Sandbox Code Playgroud)