在没有特征专业化的情况下,“借用”如何工作?

How does `Borrow` work without trait specialization?

目前,Rust 还没有 "trait specialization" 功能。据我了解,这意味着对于一个给定的类型,一个特性不能被实现多次。但是,我注意到 Borrow trait 实现了 for T where T: ?Sized,它们都是非引用类型(对吧?)。但它也适用于其他几种类型,例如 Vec<T>,这看起来像是一个专业化。

效果如何?是编译器魔法还是我误解了什么是特质特化?

简答

在这种情况下,特征特化不是必需的,因为实现是非重叠的。

长答案

Vec<T> 的特殊情况下,有许多适用于它的暗示。例如,以下内容:

impl<T> Borrow<T> for T where T: ?Sized
impl<'a, T> Borrow<T> for &'a T where T: ?Sized
impl<'a, T> Borrow<T> for &'a mut T where T: ?Sized
// other implementations are omitted for conciseness

根据这些实现,编译器可以推导出以下内容:

  1. Vec<T> 实施 Borrow<Vec<T>>
  2. &'a Vec<T> 实施 Borrow<Vec<T>>
  3. &'a mut Vec<T> 实施 Borrow<Vec<T>>

然而,none 为 Vec<T> 实现了 Borrow<[T]>。由于未提供该实现,您可以自由提供自己的实现:

impl<T> Borrow<[T]> for Vec<T>