vlambda博客
学习文章列表

学习笔记:Rust语言中AsRef和Borrow两种Trait的区别

Rust编程语言的学习笔记。内容枯燥,谨慎阅读。


前几天遇到这两种Trait,没看出有什么区别,具体情况不知道用哪个。于是在官方github找到这篇帖子,终于弄清楚了。做个笔记同时翻译一下。


来源:https://github.com/rust-lang/rust/issues/24140#issuecomment-90626264

有几个非常重要的区别:

  • Borrow is used by data structures like HashMap and BTreeMap which assume that the result of hashing or ordering based on owned and borrowed values is the same. But there are many AsRef conversions for which this isn't true. So in general, Borrow should be implemented for fewer types than AsRef, because it makes stronger guarantees.

    Borrow常被用于某些数据结构,比如HashMap和BTreeMap。这些数据结构默认基于所有值和借用值的哈希或者排序的结果相同。但对于很多AsRef的转换,这并不成立。所以大体上,Borrow应该比AsRef的可用情况更少,因为它做了更强的保障。

  • Borrow provides a blanket implementation T: Borrow<T>, which is essential for making the above collections work well. AsRef provides a different blanket implementation, basically &T: AsRef<U> whenever T: AsRef<U>, which is important for APIs like fs::open that can use a simpler and more flexible signature as a result. You can't have both blanket implementations due to coherence, so each trait is making the choice that's appropriate for its use case.

    Borrow提供了一个包裹层实现 T: Borrow<T>。这个实现从根本上实现了上述的集合数据结构。AsRef则提供了另外一个包裹层实现,大概是这样:当 T: AsRef<U> 的时候,有&T: AsRef<U> 。这对类似 fs::open 这样的API很重要,因为可以用一个更为简单和灵活的函数签名。但因为一致性问题,你不能同时使用两个包裹层实现。所以两个trait都只在合适各自应用场景的时候使用。