使用Vec :: contains时,为什么& str不会强制转换为& String?

时间:2018-02-26 10:10:03

标签: string rust

一位朋友让我解释Rust中的以下怪癖。我无法,因此这个问题:

sys.stdin.close()
sys.stdin = sys.__stdin__ 
sys.stdout.flush() 

Example on the Rust Playground

编译器会这样抱怨:

fn main() {
    let l: Vec<String> = Vec::new();
    //let ret = l.contains(&String::from(func())); // works
    let ret = l.contains(func());  // does not work
    println!("ret: {}", ret);
}

fn func() -> & 'static str {
    "hello"
}

换句话说,error[E0308]: mismatched types --> src/main.rs:4:26 | 4 | let ret = l.contains(func()); // does not work | ^^^^^^ expected struct `std::string::String`, found str | = note: expected type `&std::string::String` found type `&'static str` 不会强制&str

起初我认为这与&String有关,但这是一个红色的鲱鱼。

注释行以额外分配为代价修复了示例。

我的问题:

  • 为什么'static不强制使用&str
  • 有没有办法在没有额外分配的情况下调用&String

2 个答案:

答案 0 :(得分:2)

std::string::String是一个可扩展的堆分配数据结构,而字符串切片(str)是内存中某个不可变的固定长度字符串。字符串切片用作借用类型,通过&str。将其视为驻留在内存中某处的字符串日期的视图。这就是str强迫String无效的原因,而另一种方式完全有道理。在内存中的某处有一个堆分配的String,并且您希望使用该字符串的视图(字符串切片)。

回答你的第二个问题。无法使代码在当前表单中工作。您需要更改为字符串切片的向量(这样,将不会有额外的分配)或使用contains方法之外的其他内容。

答案 1 :(得分:0)

看来Rust开发人员intend to adjust the signature of contains to allow the example posted above to work

从某种意义上说,这是contains中的已知错误。这听起来像修复程序不允许这些类型强制执行,但允许上面的示例工作。