编写 ?Sized by itself 作为特征界限是一种惯例吗?

Is it a convention to write ?Sized by itself as a trait bound?

Programming Rust 的第 297 页,您可以找到以下内容

impl HashMap<K, V> where K: Eq + Hash
{
  fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
      where K: Borrow<Q>,
            Q: Eq + Hash
}

我以前看过这个?Sized是自己写的,其余的trait bounds在不同的行?这是约定吗?据我了解,以上内容实际上与以下内容相同?

impl HashMap<K, V> where K: Eq + Hash
{
  fn get<Q>(&self, key: &Q) -> Option<&V>
      where K: Borrow<Q>,
            Q: Eq + Hash + ?Sized
}

为什么 ?Sized 分开了?您可以在

上的类似示例中看到这一点
...
where T: AsRef<U>
      T: ?Sized, U: ?Sized
...

这是纯粹的惯例,并不是一成不变的,但它确实有一些优点。

特殊语法 ?Sized 允许编译器在不合适的情况下删除此绑定(单态化时)。因此,在某种程度上,将其拆分并放在通用定义中而不是 where 子句中是有道理的,以便于阅读,并且与其他事实不同,它不是严格的, 刚性标记。

有些库甚至更进一步,列出了通用定义中的所有标记,以及 where 子句中的所有特征。

正如@PeterHall 通过提交日志在评论中所述,在 rust 1.15 之前,?Sized 仅作为类型定义中的特征要求提供。 This PR 将此更改为我们今天的行为。