首页 > 解决方案 > Rust 和 trait 边界约定 (?Sized)

问题描述

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它自己写在哪里,其余的特征界限在不同的线上?这是一个约定吗?据我了解,以上内容实际上与以下内容相同吗?

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分裂?您可以在第 295 页的类似示例中看到这一点,

...
where T: AsRef<U>
      T: ?Sized, U: ?Sized
...

标签: rustbounding

解决方案


那是纯粹的约定,它不是一成不变的,但它确实有一些优点。

?Sized如果不合适(当单态化时),特殊语法允许编译器删除这个界限。因此,where为了便于阅读,将其拆分并将其放入通用定义而不是从句中,并将它与其他的不同,它不是一个严格、严格的标记分开这一事实确实是有道理的。

那里的一些库走得更远,列出了通用定义中的所有标记,以及where子句中的所有特征。

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


推荐阅读