Watch 25 Star 65 Fork 17

hainuo / rust ebookRuby

Create your Gitee Account
Explore and code with more than 6 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Without author's permission, this code is only for learning and cannot be used for other purposes.
Clone or download 4.56 KB
Copy Edit Web IDE Raw Blame History
hainuo authored 2015-07-08 22:38 . 语法变量引用

% Borrow and AsRef 借用和引用

The Borrow and AsRef traits are very similar, but different. Here’s a quick refresher on what these two traits mean.


Borrow 借用

The Borrow trait is used when you’re writing a datastructure, and you want to use either an owned or borrowed type as synonymous for some purpose.

Borrow借用特性用 当你正在写一个数据结构,出于某种原因,你要么使用一个自有的类型要么使用一个借用类型作为代名词的时候,可以使用Borrow借用特性

For example, HashMap has a get method which uses Borrow:


fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
    where K: Borrow<Q>,
          Q: Hash + Eq

This signature is pretty complicated. The K parameter is what we’re interested in here. It refers to a parameter of the HashMap itself:


struct HashMap<K, V, S = RandomState> {

The K parameter is the type of key the HashMap uses. So, looking at the signature of get() again, we can use get() when the key implements Borrow<Q>. That way, we can make a HashMap which uses String keys,but use &strs when we’re searching:

K参数就是 HashMap使用的 Key 的类型。所以再次看一下get()的标记,当 key 实现了Borrow<Q>后,我们可以使用get()方法。通过这种方式,我们可以做出一个HashMap ,它使用 的时String字符串键名,然而,当我们当我们查找时使用的时&str:

use std::collections::HashMap;

let mut map = HashMap::new();
map.insert("Foo".to_string(), 42);

assert_eq!(map.get("Foo"), Some(&42));

This is because the standard library has impl Borrow<str> for String.

这是因为标准库拥有一个 impl Borrow<str> for String

For most types, when you want to take an owned or borrowed type, a &T is enough. But one area where Borrow is effective is when there’s more than one kind of borrowed value. Slices are an area where this is especially true: you can have both an &[T] or a &mut [T]. If we wanted to accept both of these types, Borrow is up for it:

对于大多数类型来说,当我们想要使用一个自由类型或者借用类型时,一个&T就足够了。然而有一个地方使用Borrow借用是高效的,那就是不只是一种借用值的时候。分片是一个尤其如此地区:你可以使用&[T]或者&mut [T]这两种。如果我们想要接受这两种类型,Borrow借用弥补了这一点:

use std::borrow::Borrow;
use std::fmt::Display;

fn foo<T: Borrow<i32> + Display>(a: T) {
    println!("a is borrowed: {}", a);

let mut i = 5;

foo(&mut i);

This will print out a is borrowed: 5 twice.

这将会打印a is borrowed: 5两次。

AsRef 地址引用

The AsRef trait is a conversion trait. It’s used for converting some value to a reference in generic code. Like this:


let s = "Hello".to_string();

fn foo<T: AsRef<str>>(s: T) {
    let slice = s.as_ref();

Which should I use? 我应该用哪一个?

We can see how they’re kind of the same: they both deal with owned and borrowed versions of some type. However, they’re a bit different.


Choose Borrow when you want to abstract over different kinds of borrowing, or when you’re building a datastructure that treats owned and borrowed values in equivalent ways, such as hashing and comparison.


Choose AsRef when you want to convert something to a reference directly, and you’re writing generic code.


Comment ( 0 )

Sign in for post a comment