我有以下代码:
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()替代来解决这个问题.
因为ToOwned已实施for T where T: Clone,并Clone已实施for &T.您需要大致了解模式如何匹配&self工作时都T和&T可用.使用伪语法进行说明,
str ? Stringstr 不匹配 &self&str(自动REF)相匹配&self以self == str因此ToOwned<str>踢了.
&str ? String&str匹配&self带self == str因此ToOwned<str>踢了.
&&str ? &str&&str匹配&self带self == &str因此ToOwned<&T>踢了.
请注意,在这种情况下,auto-deref永远不会启动,因为&T在T可能的情况下总是匹配,这会降低复杂性.另请注意,auto-ref仅启动一次(对于每个auto-deref'd类型再次启动).
算法的核心是:
- 对于每个"解除引用步骤"
U(即设置U = T然后U = *T,......)
- 如果有一种
bar接收器类型(方法中的类型self)U完全匹配的方法,请使用它("按值方法")- 否则,添加一个auto-ref(take
&或&mutof receiver),如果某个方法的接收器匹配&U,则使用它("autorefd方法")
FWIW,.into()通常比它更漂亮.to_owned()(特别是当暗示类型时;即使没有),所以我建议这里.但是,您仍然需要手动取消引用.