&& str.to_owned()不会产生String

vir*_*tor 3 reference rust

我有以下代码:

use std::collections::HashMap;
fn main() {
    let xs: Vec<&str> = vec!("a", "b", "c", "d");
    let ys: Vec<i32> = vec!(1, 2, 3, 4);

    let mut map: HashMap<String,i32> = HashMap::new();
    for (x,y) in xs.iter().zip(ys) {
        map.insert(x.to_owned(), y);
    }
    println!("{:?}", map);
}
Run Code Online (Sandbox Code Playgroud)

哪会导致错误:

<anon>:8:20: 8:32 error: mismatched types:
 expected `collections::string::String`,
    found `&str`
(expected struct `collections::string::String`,
    found &-ptr) [E0308]
<anon>:8         map.insert(x.to_owned(), y);
Run Code Online (Sandbox Code Playgroud)

但这对我没有意义.x应该&&str在这一点上.那么为什么在这一点上不会以同样的方式&&str.to_owned()自动化呢?(为什么是一个?)Derefx.to_string()x.to_owned()&str

我知道我可以通过使用x.to_string()xs.into_iter()替代来解决这个问题.

Vee*_*rac 7

因为ToOwned已实施for T where T: Clone,并Clone已实施for &T.您需要大致了解模式如何匹配&self工作时都T&T可用.使用伪语法进行说明,

str ? String

  • str 不匹配 &self
  • &str(自动REF)相匹配&selfself == str

因此ToOwned<str>踢了.

&str ? String

  • &str匹配&selfself == str

因此ToOwned<str>踢了.

&&str ? &str

  • &&str匹配&selfself == &str

因此ToOwned<&T>踢了.

请注意,在这种情况下,auto-deref永远不会启动,因为&TT可能的情况下总是匹配,这会降低复杂性.另请注意,auto-ref仅启动一次(对于每个auto-deref'd类型再次启动).

要从huon那里复制比我更好的答案,

算法的核心是:

  • 对于每个"解除引用步骤" U(即设置U = T然后U = *T,......)
    1. 如果有一种bar接收器类型(方法中的类型self)U完全匹配的方法,请使用它("按值方法")
    2. 否则,添加一个auto-ref(take &&mutof receiver),如果某个方法的接收器匹配&U,则使用它("autorefd方法")

FWIW,.into()通常比它更漂亮.to_owned()(特别是当暗示类型时;即使没有),所以我建议这里.但是,您仍然需要手动取消引用.