【问题标题】:Rust and trait bounds conventions (?Sized)Rust 和 trait 边界约定 (?Sized)
【发布时间】:2019-09-20 10:43:44
【问题描述】:

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 被拆分了?您可以在page 295 上的类似示例中看到这一点,

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

【问题讨论】:

    标签: rust bounding


    【解决方案1】:

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

    特殊语法?Sized 允许编译器在不合适的情况下删除此绑定(当单态化时)。因此,为了便于阅读,将其拆分并将其放在通用定义中而不是 where 子句中,并且将它与其他的不同,它不是一个严格的、死板的事实分开确实是有意义的标记。

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

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

    【讨论】:

    • 这种区别也有历史原因。早期版本的编译器不允许 ?Sizedwhere 子句中。
    • @E_net4theMeta-RemoveR 这可能是“真正的”答案。
    • @PeterHall 如果我找到参考资料,我会将其转为答案。我所知道的只是口口相传,我还没有完全验证。
    • @E_net4theMeta-RemoveR github.com/rust-lang/rust/pull/37791 在 Rust 1.15 中稳定
    • 所以你找到了。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2017-05-27
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多