如何使用向量的字符串切片

时间:2019-06-27 21:32:04

标签: rust

我想知道为什么这样

fn main() {
    let v: Vec<&str> = Vec::new();
    let s: &str = v.get(0).unwrap();
    let new_string = String::from(s);
    println!("{}", new_string);
}

但不是这个:

fn main() {
    let v: Vec<&str> = Vec::new();
    let s = v.get(0).unwrap();
    let new_string = String::from(s);
    println!("{}", new_string);
}

第二个代码段出现以下错误:

let new_string = String::from(s);
                  ^^^^^^^^^^^^ the trait `std::convert::From<&&str>` is not implemented for `std::string::String`

1 个答案:

答案 0 :(得分:0)

Vec::<T>::get()方法返回一个Option<&T>,即对向量的引用选项。因为向量已经包含引用(&str),所以在您的情况下,get()返回Option<&&str>

现在,您的第一个示例进行编译的原因是,通过明确说明s变量的类型,会导致deref coercion触发,也就是说,编译器将自动插入解引用运算符:

// You write this:
let s: &str = v.get(0).unwrap();

// Compiler actually does this:
let s: &str = *v.get(0).unwrap();

然后,因为存在existsFrom<&str>特性String的实现,所以编译器接受String::from(s)调用。

但是,在第二篇文章中,没有显式类型注释,则分配给s的类型是&&str

let s: &&str = v.get(0).unwrap();

这通过String::from()方法改变了情况:From<&&str>没有String实现,并且编译器无法编译代码。

这里的逻辑问题是,当将s用作from()的参数时,为什么在这种情况下不发生反引用强制?答案是通用方法不会发生反引用强制,而String::from是通用方法,因为它依赖于From特性的类型参数。编译器无法执行反强制,因为totally possible(原则上)同时具有From<&str>From<&&str>方法,它们可能会做不同的事情。

即使From<&&str>现在不存在,并且编译器将应用deref强制,它也会使代码对未来的发展变得脆弱:如果出于某种原因在将来的版本中添加了From<&&str>在标准库中,您的代码可能会无声地中断,因为它现在将调用与以前不同的方法,并且逻辑可能不同。

(自然地,我并不是说在未来的libstd版本中确实会添加From<&&str>;这是适用于任何特征,在任何代码库中的通用推理)。

相关问题