Rust 中定义空 impl 的目的是什么?

Lan*_*ard 5 rust

例如:

impl<T: ?Sized> cmp::Eq for $t<T> {}
Run Code Online (Sandbox Code Playgroud)

如果没有实现,为什么还要编写这段代码呢?它发生在很多地方,特别是与方程式有关的地方。

#[unstable(feature = "structural_match", issue = "31434")]
impl<T: ?Sized> StructuralPartialEq for $t<T> {}

#[unstable(feature = "structural_match", issue = "31434")]
impl<T: ?Sized> StructuralEq for $t<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Copy for $t<T> {}

impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}
unsafe impl<T: ?Sized> Freeze for *const T {}
unsafe impl<T: ?Sized> Freeze for *mut T {}
unsafe impl<T: ?Sized> Freeze for &T {}
unsafe impl<T: ?Sized> Freeze for &mut T {}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 8

特征可以用空来实现impl {}没有方法,或者它的所有方法都有默认实现,则可以使用空块来实现特征。这些被称为“标记”或“标签”特征。

\n

无开销的抽象:Rust 中的特征有标记特征的描述:

\n
\n

Rust 有一些对类型进行分类的“标记”:SendSyncCopySized。这些标记只是具有空体的特征,然后可以在泛型和特征对象中使用。标记可以在库中定义,并且它们自动提供-style 实现:例如,#[derive]如果所有 a 类型组件都是,那么该类型也是。Send正如我们之前所看到的,这些标记可能非常强大:Send标记是 Rust 保证线程安全的方式。

\n
\n

Eq是另一个常见的标记特征。它是已经实现的类型的标签PartialEq,表明相等操作实际上不是“部分”的;它是完全自反、对称和传递的。实现它不需要任何额外的实现,因为eq实现是从类型的impl PartialEq { ... }块中获取的。

\n
\n
pub trait Eq: PartialEq<Self> { }\n
Run Code Online (Sandbox Code Playgroud)\n

等价比较的特征是等价关系。

\n

这意味着,除了a == ba != b是严格逆元之外,相等性还必须是(对于所有a,bc):

\n
    \n
  • 自反:a == a;
  • \n
  • 对称:a == b 意味着 b == a;和
  • \n
  • 传递性: a == b 和 b == c 意味着 a == c。\n编译器无法检查此属性,因此Eq意味着PartialEq,并且没有额外的方法。
  • \n
\n
可衍生的
\n

该特性可以与 一起使用#[derive]。派生时,由于Eq没有额外的方法,它只是通知编译器这是一个等价关系而不是部分等价关系。请注意,该derive策略要求所有字段都是Eq,这并不是\xe2\x80\x99 总是需要的。

\n
我该如何实施Eq
\n

如果您无法使用该derive策略,请指定您的类型实现Eq,它没有方法:

\n
enum BookFormat { Paperback, Hardback, Ebook }\nstruct Book {\n    isbn: i32,\n    format: BookFormat,\n}\nimpl PartialEq for Book {\n    fn eq(&self, other: &Self) -> bool {\n        self.isbn == other.isbn\n    }\n}\nimpl Eq for Book {}\n
Run Code Online (Sandbox Code Playgroud)\n
\n