在下面的代码中,我定义了一个名为Wrap
(局部类型)的 struct 来包装值,以及一个名为WrapOut
(局部特征)的特征来提取该值.我在HashMap
(外部类型)的键和值上都使用了Wrap
.此版本的代码可以按预期运行
use std::collections::HashMap;
struct Wrap<T> {
val: T
}
trait WrapOut<T> {
fn wrap_out(self) -> T;
}
impl<T, U> WrapOut<HashMap<T, U>> for HashMap<Wrap<T>, Wrap<U>>
where T: std::cmp::Eq + std::hash::Hash
{
fn wrap_out(self) -> HashMap<T, U> {
println!("both");
self.into_iter().map(|(k, v)| (k.val, v.val)).collect()
}
}
impl<T, U> WrapOut<HashMap<T, U>> for HashMap<T, Wrap<U>>
where T: std::cmp::Eq + std::hash::Hash
{
fn wrap_out(self) -> HashMap<T, U> {
println!("only val");
self.into_iter().map(|(k, v)| (k, v.val)).collect()
}
}
impl<T, U> WrapOut<HashMap<T, U>> for HashMap<Wrap<T>, U>
where T: std::cmp::Eq + std::hash::Hash
{
fn wrap_out(self) -> HashMap<T, U> {
println!("only key");
self.into_iter().map(|(k, v)| (k.val, v)).collect()
}
}
fn main() {
let m1 = HashMap::<Wrap<u32>, Wrap<u32>>::new();
let m2 = HashMap::<u32, Wrap<u32>>::new();
let m3 = HashMap::<Wrap<u32>, u32>::new();
let m1: HashMap<u32, u32> = m1.wrap_out();
let m2: HashMap<u32, u32> = m2.wrap_out();
let m3: HashMap<u32, u32> = m3.wrap_out();
}
当我通过将泛型类型参数更改为关联类型来重写WrapOut
时,发生了冲突的实现错误.
我想知道为什么impl<T, U> WrapOut for HashMap<Wrap<T>, U>
报告了冲突,而impl<T, U> WrapOut for HashMap<T, Wrap<U>>
没有.
trait WrapOut {
type Target;
fn wrap_out(self) -> Self::Target;
}
impl<T, U> WrapOut for HashMap<Wrap<T>, Wrap<U>>
where T: std::cmp::Eq + std::hash::Hash
{
type Target = HashMap<T, U>;
fn wrap_out(self) -> HashMap<T, U> {
println!("both");
self.into_iter().map(|(k, v)| (k.val, v.val)).collect()
}
}
impl<T, U> WrapOut for HashMap<T, Wrap<U>>
where T: std::cmp::Eq + std::hash::Hash
{
type Target = HashMap<T, U>;
fn wrap_out(self) -> HashMap<T, U> {
println!("only val");
self.into_iter().map(|(k, v)| (k, v.val)).collect()
}
}
// Occurs Error!
impl<T, U> WrapOut for HashMap<Wrap<T>, U>
where T: std::cmp::Eq + std::hash::Hash
{
type Target = HashMap<T, U>;
fn wrap_out(self) -> HashMap<T, U> {
println!("only key");
self.into_iter().map(|(k, v)| (k.val, v)).collect()
}
}
错误信息:
|
51 | impl<T, U> WrapOut for HashMap<Wrap<T>, Wrap<U>>
| ------------------------------------------------ first implementation here
...
75 | impl<T, U> WrapOut for HashMap<Wrap<T>, U>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `HashMap<Wrap<_>, Wrap<_>>`
希望您能解释为什么关联的类型版本的代码不能工作,以及背后的原因? 哪种版本的代码更好?