无法使用任意长度的切片将数组传递给“From”特质

3

我正在尝试为我的类型实现From<&[&str]>。它应该消耗任意长度的行(仅在运行时已知),并从这些行中获取数据。编译器报错说,&[&str; 2]不是&[&str],即无法将固定大小的切片转换为具有任意长度的切片。确切的消息是:the trait 'From<&[&str; 2]>' is not implemented for 'LineEater'

这是我的尝试:

fn main() {
    let data = ["foo", "bar"];
    
    // works
    foo(&data);

    // doesn't work
    LineEater::from(&data);

    // also doesn't work
    let data: &[&str] = data.into();
    LineEater::from(&data);
}

struct LineEater;
impl From<&[&str]> for LineEater {
    fn from(_lines: &[&str]) -> Self {
        todo!()
    }
}

fn foo(_slice: &[&str]) {}
Playground是一个在线运行Rust代码的工具。这段代码中,调用foo()可以正常工作,但调用from则不行。在第一个情况下,Rust可以将[&str; 2]“转换”为&[&str],但后者则不能。为什么会这样?如何修复呢?本段代码所用的Rust版本为1.55-nightly。
2个回答

5
您可以使用范围运算符:
fn main() {
    let data = ["foo", "bar"];
    LineEater::from(&data[..]);
}

struct LineEater;
impl From<&[&str]> for LineEater {
    fn from(_lines: &[&str]) -> Self {
        todo!()
    }
}

Playground链接

或者您可以使用全限定语法来告诉Rust,您想要使用&[&str]From实现:

fn main() {
    let data = ["foo", "bar"];
    <LineEater as From<&[&str]>>::from(&data);
}

struct LineEater;
impl From<&[&str]> for LineEater {
    fn from(_lines: &[&str]) -> Self {
        todo!()
    }
}

Playground链接


2
AsRef::as_refBorrow::borrow方法也可以执行转换,同时还可以使用as进行强制类型转换(&data as &[&str])。 - Aiden4

1
你需要将数组强制转换成切片:
let data: &[&str] = &["foo", "bar"];

游乐场

同时也可以查看切片文档中的第一个示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接