最小示例:
use std::collections::HashSet;
struct Something {
a: HashSet<Point>,
b: HashSet<Point>
}
impl Something {
fn TEST(&self) {
let new = self.a | self.b;
}
}
#[derive(Eq, PartialEq, Hash, Copy, Clone)]
struct Point {
x: usize,
y: usize
}
检查它on the Rust Playground。如果你试图编译这段代码,Rust会用error[E0369]: no implementation for std::collections::HashSet<Point> | std::collections::HashSet<Point>
抱怨。
但是根据HashSet的文档,至少根据我的理解,应该为HashSet实现BitOr
特性,其中T: Eq + Hash + Clone
,Point
显然在这里,那么实际上发生了什么,我如何修复它?
1条答案
按热度按时间c0vxltue1#
进一步了解
HashSet
的BitOr
实现:BitOr
仅针对对HashSet
的引用而实现,不针对拥有的值而实现。按如下所示重新编写
Something::TEST
的实现将按预期进行编译。请注意,这里使用了对
self.a
和self.b
的引用。像按位或这样的操作只对容器的引用而不是容器类型本身实现,这一事实一开始可能看起来出乎意料,但是当你考虑到它们预期的所有权语义时,它就完全有意义了。它同时拥有
self
和rhs
。如果BitOr
(或任何其它二元运算符特征)在不是Copy
的类型的目录中实现,那么它将取得|
的自变量的所有权。使a | b
导致a或b被移动将是相当出乎意料的。因此,标准库仅实现用于引用集合(其是Copy
能力的)的二元运算符,而不是用于引用集合值本身的二元运算符。