Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b60c3e2
Closes #15919
bombless Apr 30, 2015
4c8b813
Closes #15919
bombless Apr 30, 2015
51a1e83
doc: Remove mention of 30 minute intro
brson May 8, 2015
7d9e605
Add error explanation for E0317.
meqif May 10, 2015
c0412bc
Fix documentation URL in diagnostic message.
meqif May 10, 2015
f3a3684
Add error explanation for E0154.
meqif May 10, 2015
e7fa00a
Add error explanation for E0259.
meqif May 10, 2015
60ec4ab
Add error explanation for E0260.
meqif May 10, 2015
bff1707
Fixed one textual mistake and one casing error.
michal-czardybon May 8, 2015
ef03055
Improve wording in error explanation.
meqif May 11, 2015
aa529ef
Add missing keyword in `extern crate` declarations.
meqif May 11, 2015
d13f765
Make mention of `if` more generic
frewsxcv May 12, 2015
93c21c7
Correct claims about &T's Copyness.
Ms2ger May 12, 2015
6faa8d6
Add a link to the error index to the main doc page.
michaelsproul May 12, 2015
e780fb2
TRPL: Borrow and AsRef
steveklabnik Apr 30, 2015
393a37e
Correct various small points, expand some sections, while avoiding
nikomatsakis May 12, 2015
6987900
Rollup merge of #24987 - bombless:large-array, r=pnkfelix
steveklabnik May 12, 2015
cae0844
Rollup merge of #24996 - steveklabnik:gh24163, r=aturon
steveklabnik May 12, 2015
40a5f3c
Rollup merge of #25220 - brson:doc1, r=steveklabnik
steveklabnik May 12, 2015
57852e9
Rollup merge of #25221 - michal-czardybon:master, r=steveklabnik
steveklabnik May 12, 2015
b814884
Rollup merge of #25267 - meqif:explain_e0317, r=alexcrichton
steveklabnik May 12, 2015
5096ce6
Rollup merge of #25322 - frewsxcv:patch-23, r=steveklabnik
steveklabnik May 12, 2015
29dd563
Rollup merge of #25327 - Ms2ger:copy-ref, r=pnkfelix
steveklabnik May 12, 2015
b3c92d9
Rollup merge of #25331 - michaelsproul:err-idx-doc-link, r=Manishearth
steveklabnik May 12, 2015
34bc44f
Rollup merge of #25335 - nikomatsakis:updates-to-reference-manual, r=…
steveklabnik May 12, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/doc/trpl/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [Concurrency](concurrency.md)
* [Error Handling](error-handling.md)
* [FFI](ffi.md)
* [Borrow and AsRef](borrow-and-asref.md)
* [Syntax and Semantics](syntax-and-semantics.md)
* [Variable Bindings](variable-bindings.md)
* [Functions](functions.md)
Expand Down
93 changes: 93 additions & 0 deletions src/doc/trpl/borrow-and-asref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
% Borrow and AsRef

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

[borrow]: ../std/borrow/trait.Borrow.html
[asref]: ../std/convert/trait.AsRef.html

# 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.

For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`:

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

[hashmap]: ../std/collections/struct.HashMap.html
[get]: ../std/collections/struct.HashMap.html#method.get

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

```rust,ignore
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 `&str`s when we’re searching:

```rust
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`.

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:

```
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(&i);
foo(&mut i);
```

This will print out `a is borrowed: 5` twice.

# AsRef

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

```rust
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.
5 changes: 5 additions & 0 deletions src/libcollections/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ use self::Cow::*;
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
///
/// `Borrow` is very similar to, but different than, `AsRef`. See
/// [the book][book] for more.
///
/// [book]: ../../book/borrow-and-asref.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
/// Immutably borrows from an owned value.
Expand Down
5 changes: 5 additions & 0 deletions src/libcore/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ use marker::Sized;

/// A cheap, reference-to-reference conversion.
///
/// `AsRef` is very similar to, but different than, `Borrow`. See
/// [the book][book] for more.
///
/// [book]: ../../book/borrow-and-asref.html
///
/// # Examples
///
/// Both `String` and `&str` implement `AsRef<str>`:
Expand Down