When a type implements AsRef<T>, that means you can borrow a &T from it efficiently

    1. trait AsRef<T: ?Sized> {
    2. fn as_ref(&self) -> &T;
    3. }

    AsRef 这个trait的作用是为了扩展函数入参的多样性,例如 std::fs::File::open 是这样定义的

    1. fn open<P: AsRef<Path>>(path: P) -> Result<File>

    也就是说,任何实现了 AsRef 类型都可以作为参数传入,rust2018后推荐如下写法

    1. fn open(path: impl AsRef<Path>) -> Result<File>

    But with this signature, open accepts anything it can borrow a &Path from—that is, anything that implements AsRef. Such types include String and str

    1. let dot_emacs = std::fs::File::open("/home/jimb/.emacs")?;

    再举个例子

    例如我们要自己为Hello这个Struct实现一个AsRef trait

    1. struct Hello {
    2. name: String,
    3. }
    4. impl AsRef<String> for Hello {
    5. fn as_ref(&self) -> &String {
    6. &self.name
    7. }
    8. }
    9. fn do_sth(param: impl AsRef<String>) {
    10. let str = param.as_ref();
    11. println!("do sth with {}", str);
    12. }
    13. fn main() {
    14. let hello = Hello {
    15. name: String::from("hello"),
    16. };
    17. do_sth(&hello);
    18. }

    这样一来Hello这个struct也能作为参数传入do_sth这个函数中