简体   繁体   English

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

[英]Why does a &str not coerce to a &String when using Vec::contains?

A friend asked me to explain the following quirk in Rust. 一位朋友让我解释Rust中的以下怪癖。 I was unable to, hence this question: 我无法,因此这个问题:

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"
}

Example on the Rust Playground Rust Playground上的示例

The compiler will complain like this: 编译器会这样抱怨:

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`

In other words, &str does not coerce with &String . 换句话说, &str不会强制使用&String

At first I thought it was to do with 'static , however that is a red herring. 起初我认为这与'static ,然而这是一个红色的鲱鱼。

The commented line fixes the example at the cost of an extra allocation. 注释行以额外分配为代价修复了示例。

My questions: 我的问题:

  • Why doesn't &str coerce with &String ? 为什么&str强制使用&String
  • Is there a way to make the call to contains work without the extra allocation? 有没有办法让调用contains工作而没有额外的分配?

Your first question should be answer already by @Marko. 你的第一个问题应该由@Marko回答。

Your second question, should be easy to answer as well, just use a closure: 你的第二个问题也应该很容易回答,只需使用一个闭包:

let ret = l.iter().any(|x| x == func());

Edit: 编辑:

Not the "real" answer anymore, but I let this here for people who might be interested in a solution for this. 不再是“真正的”答案,但我在这里为那些可能对此解决方案感兴趣的人提供了这个答案。

std::string::String is a growable, heap-allocated data structure whereas string slice ( str ) is an immutable fixed-length string somewhere in memory. std::string::String是一个可增长的堆分配数据结构,而字符串slice( str )是内存中某个不可变的固定长度字符串。 String slice is used as a borrowed type, via &str . 字符串切片用作借用类型,通过&str Consider it as view to some string date that resides somewhere in memory. 将其视为驻留在内存中某处的字符串日期的视图。 That is why it does not make sense for str to coerce to String , while the other way around perfectly makes sense. 这就是为什么它没有意义的str要挟到String ,而周围的其他方法完全是有道理的。 You have a heap-allocated String somewhere in memory and you want to use a view (a string slice) to that string. 您在内存中的某处有一个堆分配的String ,并且您希望使用该字符串的视图(字符串切片)。

To answer your second question. 回答你的第二个问题。 There is no way to make the code work in the current form. 无法使代码在当前表单中工作。 You either need to change to a vector of string slices (that way, there will be no extra allocation) or use something other then contains method. 您需要更改为字符串切片的向量(这样,将不会有额外的分配)或使用其他contains方法的其他contains

It seems that the Rust developers intend to adjust the signature of contains to allow the example posted above to work . 似乎Rust开发人员打算调整contains的签名,以允许上面发布的示例工作

In some sense, this is a known bug in contains . 从某种意义上说,这是contains的已知错误。 It sounds like the fix won't allow those types to coerce, but will allow the above example to work. 听起来修复程序不允许这些类型强制执行,但允许上面的示例工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM