When a type implements
AsRef<T>
, that means you can borrow a&T
from it efficiently
trait AsRef<T: ?Sized> {
fn as_ref(&self) -> &T;
}
AsRef 这个trait的作用是为了扩展函数入参的多样性,例如 std::fs::File::open
是这样定义的
fn open<P: AsRef<Path>>(path: P) -> Result<File>
也就是说,任何实现了 AsRef
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
let dot_emacs = std::fs::File::open("/home/jimb/.emacs")?;
再举个例子
例如我们要自己为Hello这个Struct实现一个AsRef trait
struct Hello {
name: String,
}
impl AsRef<String> for Hello {
fn as_ref(&self) -> &String {
&self.name
}
}
fn do_sth(param: impl AsRef<String>) {
let str = param.as_ref();
println!("do sth with {}", str);
}
fn main() {
let hello = Hello {
name: String::from("hello"),
};
do_sth(&hello);
}
这样一来Hello这个struct也能作为参数传入do_sth这个函数中