我有以下代码:
use std::collections::HashMap; fn main() { let xs: Vec<&str> = vec!("a", "b", "c", "d"); let ys: Vec= vec!(1, 2, 3, 4); let mut map: HashMap = HashMap::new(); for (x,y) in xs.iter().zip(ys) { map.insert(x.to_owned(), y); } println!("{:?}", map); }
哪会导致错误:
:8:20: 8:32 error: mismatched types: expected `collections::string::String`, found `&str` (expected struct `collections::string::String`, found &-ptr) [E0308] :8 map.insert(x.to_owned(), y);
但这对我没有意义.x
应该&&str
在这一点上.那么为什么在这一点上不会以同样的方式&&str.to_owned()
自动化呢?(为什么是一个?)Deref
x.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 ? String
str
不匹配 &self
&str
(自动REF)相匹配&self
以self == str
因此ToOwned
踢了.
&str ? String
&str
匹配&self
带self == str
因此ToOwned
踢了.
&&str ? &str
&&str
匹配&self
带self == &str
因此ToOwned<&T>
踢了.
请注意,在这种情况下,auto-deref永远不会启动,因为&T
在T
可能的情况下总是匹配,这会降低复杂性.另请注意,auto-ref仅启动一次(对于每个auto-deref'd类型再次启动).
要从huon那里复制比我更好的答案,
算法的核心是:
对于每个"解除引用步骤"
U
(即设置U = T
然后U = *T
,......)
如果有一种
bar
接收器类型(方法中的类型self
)U
完全匹配的方法,请使用它("按值方法")否则,添加一个auto-ref(take
&
或&mut
of receiver),如果某个方法的接收器匹配&U
,则使用它("autorefd方法")
FWIW,.into()
通常比它更漂亮.to_owned()
(特别是当暗示类型时;即使没有),所以我建议这里.但是,您仍然需要手动取消引用.