Skip to content

Commit 52b4123

Browse files
committed
---
yaml --- r: 124571 b: refs/heads/auto c: fb4c3f0 h: refs/heads/master i: 124569: 32f956f 124567: 2680564 v: v3
1 parent 1831007 commit 52b4123

File tree

111 files changed

+2317
-576
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+2317
-576
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1313
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1414
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1515
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
16-
refs/heads/auto: 7ee45aa6e5cf6114517baf30a61662ec5bdf9e40
16+
refs/heads/auto: fb4c3f0af287423489e54b6415452d3f7881b592
1717
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1818
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1919
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
% The Strings Guide
2+
3+
# Strings
4+
5+
Strings are an important concept to master in any programming language. If you
6+
come from a managed language background, you may be surprised at the complexity
7+
of string handling in a systems programming language. Efficient access and
8+
allocation of memory for a dynamically sized structure involves a lot of
9+
details. Luckily, Rust has lots of tools to help us here.
10+
11+
A **string** is a sequence of unicode scalar values encoded as a stream of
12+
UTF-8 bytes. All strings are guaranteed to be validly-encoded UTF-8 sequences.
13+
Additionally, strings are not null-terminated and can contain null bytes.
14+
15+
Rust has two main types of strings: `&str` and `String`.
16+
17+
## &str
18+
19+
The first kind is a `&str`. This is pronounced a 'string slice.' String literals
20+
are of the type `&str`:
21+
22+
```{rust}
23+
let string = "Hello there.";
24+
```
25+
26+
Like any Rust type, string slices have an associated lifetime. A string literal
27+
is a `&'static str`. A string slice can be written without an explicit
28+
lifetime in many cases, such as in function arguments. In these cases the
29+
lifetime will be inferred:
30+
31+
```{rust}
32+
fn takes_slice(slice: &str) {
33+
println!("Got: {}", slice);
34+
}
35+
```
36+
37+
Like vector slices, string slices are simply a pointer plus a length. This
38+
means that they're a 'view' into an already-allocated string, such as a
39+
`&'static str` or a `String`.
40+
41+
## String
42+
43+
A `String` is a heap-allocated string. This string is growable, and is also
44+
guaranteed to be UTF-8.
45+
46+
```{rust}
47+
let mut s = "Hello".to_string();
48+
println!("{}", s);
49+
50+
s.push_str(", world.");
51+
println!("{}", s);
52+
```
53+
54+
You can coerce a `String` into a `&str` with the `as_slice()` method:
55+
56+
```{rust}
57+
fn takes_slice(slice: &str) {
58+
println!("Got: {}", slice);
59+
}
60+
61+
fn main() {
62+
let s = "Hello".to_string();
63+
takes_slice(s.as_slice());
64+
}
65+
```
66+
67+
You can also get a `&str` from a stack-allocated array of bytes:
68+
69+
```{rust}
70+
use std::str;
71+
72+
let x: &[u8] = &[b'a', b'b'];
73+
let stack_str: &str = str::from_utf8(x).unwrap();
74+
```
75+
76+
## Best Practices
77+
78+
### `String` vs. `&str`
79+
80+
In general, you should prefer `String` when you need ownership, and `&str` when
81+
you just need to borrow a string. This is very similar to using `Vec<T>` vs. `&[T]`,
82+
and `T` vs `&T` in general.
83+
84+
This means starting off with this:
85+
86+
```{rust,ignore}
87+
fn foo(s: &str) {
88+
```
89+
90+
and only moving to this:
91+
92+
```{rust,ignore}
93+
fn foo(s: String) {
94+
```
95+
96+
If you have good reason. It's not polite to hold on to ownership you don't
97+
need, and it can make your lifetimes more complex. Furthermore, you can pass
98+
either kind of string into `foo` by using `.as_slice()` on any `String` you
99+
need to pass in, so the `&str` version is more flexible.
100+
101+
### Comparisons
102+
103+
To compare a String to a constant string, prefer `as_slice()`...
104+
105+
```{rust}
106+
fn compare(string: String) {
107+
if string.as_slice() == "Hello" {
108+
println!("yes");
109+
}
110+
}
111+
```
112+
113+
... over `to_string()`:
114+
115+
```{rust}
116+
fn compare(string: String) {
117+
if string == "Hello".to_string() {
118+
println!("yes");
119+
}
120+
}
121+
```
122+
123+
Converting a `String` to a `&str` is cheap, but converting the `&str` to a
124+
`String` involves an allocation.
125+
126+
## Other Documentation
127+
128+
* [the `&str` API documentation](/std/str/index.html)
129+
* [the `String` API documentation](std/string/index.html)

branches/auto/src/libcollections/btree.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,12 @@ impl<K: Clone + Ord, V: Clone> Leaf<K, V> {
365365
return (Node::new_leaf(self.clone().elts), false);
366366
}
367367
//If there is an index, insert at that index.
368-
_ => {
369-
if index.unwrap() >= self.elts.len() {
368+
Some(i) => {
369+
if i >= self.elts.len() {
370370
self.elts.push(to_insert.clone());
371371
}
372372
else {
373-
self.elts.insert(index.unwrap(), to_insert.clone());
373+
self.elts.insert(i, to_insert.clone());
374374
}
375375
}
376376
}
@@ -526,16 +526,16 @@ impl<K: Clone + Ord, V: Clone> Branch<K, V> {
526526
self.clone().rightmost_child),
527527
outcome);
528528
}
529-
_ => {
530-
if index.unwrap() == self.elts.len() {
529+
Some(i) => {
530+
if i == self.elts.len() {
531531
let new_outcome = self.clone().rightmost_child.insert(k.clone(),
532532
v.clone(),
533533
ub.clone());
534534
new_branch = new_outcome.clone().val0();
535535
outcome = new_outcome.val1();
536536
}
537537
else {
538-
let new_outcome = self.elts.get(index.unwrap()).left.clone().insert(k.clone(),
538+
let new_outcome = self.elts.get(i).left.clone().insert(k.clone(),
539539
v.clone(),
540540
ub.clone());
541541
new_branch = new_outcome.clone().val0();
@@ -547,11 +547,11 @@ impl<K: Clone + Ord, V: Clone> Branch<K, V> {
547547
//If we have a leaf, we do not need to resize the tree,
548548
//so we can return false.
549549
LeafNode(..) => {
550-
if index.unwrap() == self.elts.len() {
550+
if i == self.elts.len() {
551551
self.rightmost_child = box new_branch.clone();
552552
}
553553
else {
554-
self.elts.get_mut(index.unwrap()).left = box new_branch.clone();
554+
self.elts.get_mut(i).left = box new_branch.clone();
555555
}
556556
return (Node::new_branch(self.clone().elts,
557557
self.clone().rightmost_child),
@@ -589,13 +589,13 @@ impl<K: Clone + Ord, V: Clone> Branch<K, V> {
589589
self.clone().rightmost_child),
590590
false);
591591
}
592-
_ => {
593-
self.elts.insert(new_elt_index.unwrap(), new_elt);
594-
if new_elt_index.unwrap() + 1 >= self.elts.len() {
592+
Some(i) => {
593+
self.elts.insert(i, new_elt);
594+
if i + 1 >= self.elts.len() {
595595
self.rightmost_child = branch.clone().rightmost_child;
596596
}
597597
else {
598-
self.elts.get_mut(new_elt_index.unwrap() + 1).left =
598+
self.elts.get_mut(i + 1).left =
599599
branch.clone().rightmost_child;
600600
}
601601
}

branches/auto/src/libcollections/slice.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -277,21 +277,33 @@ impl<T: Clone> Iterator<Vec<T>> for Permutations<T> {
277277

278278
/// Extension methods for vector slices with cloneable elements
279279
pub trait CloneableVector<T> {
280-
/// Copy `self` into a new owned vector
281-
fn to_owned(&self) -> Vec<T>;
280+
/// Copy `self` into a new vector
281+
fn to_vec(&self) -> Vec<T>;
282+
283+
/// Deprecated. Use `to_vec`
284+
#[deprecated = "Replaced by `to_vec`"]
285+
fn to_owned(&self) -> Vec<T> {
286+
self.to_vec()
287+
}
282288

283289
/// Convert `self` into an owned vector, not making a copy if possible.
284-
fn into_owned(self) -> Vec<T>;
290+
fn into_vec(self) -> Vec<T>;
291+
292+
/// Deprecated. Use `into_vec`
293+
#[deprecated = "Replaced by `into_vec`"]
294+
fn into_owned(self) -> Vec<T> {
295+
self.into_vec()
296+
}
285297
}
286298

287299
/// Extension methods for vector slices
288300
impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
289301
/// Returns a copy of `v`.
290302
#[inline]
291-
fn to_owned(&self) -> Vec<T> { Vec::from_slice(*self) }
303+
fn to_vec(&self) -> Vec<T> { Vec::from_slice(*self) }
292304

293305
#[inline(always)]
294-
fn into_owned(self) -> Vec<T> { self.to_owned() }
306+
fn into_vec(self) -> Vec<T> { self.to_vec() }
295307
}
296308

297309
/// Extension methods for vectors containing `Clone` elements.
@@ -325,7 +337,7 @@ impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
325337
fn permutations(self) -> Permutations<T> {
326338
Permutations{
327339
swaps: ElementSwaps::new(self.len()),
328-
v: self.to_owned(),
340+
v: self.to_vec(),
329341
}
330342
}
331343

@@ -888,7 +900,7 @@ mod tests {
888900
fn test_slice() {
889901
// Test fixed length vector.
890902
let vec_fixed = [1i, 2, 3, 4];
891-
let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
903+
let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_vec();
892904
assert_eq!(v_a.len(), 3u);
893905
let v_a = v_a.as_slice();
894906
assert_eq!(v_a[0], 2);
@@ -897,15 +909,15 @@ mod tests {
897909

898910
// Test on stack.
899911
let vec_stack = &[1i, 2, 3];
900-
let v_b = vec_stack.slice(1u, 3u).to_owned();
912+
let v_b = vec_stack.slice(1u, 3u).to_vec();
901913
assert_eq!(v_b.len(), 2u);
902914
let v_b = v_b.as_slice();
903915
assert_eq!(v_b[0], 2);
904916
assert_eq!(v_b[1], 3);
905917

906918
// Test `Box<[T]>`
907919
let vec_unique = vec![1i, 2, 3, 4, 5, 6];
908-
let v_d = vec_unique.slice(1u, 6u).to_owned();
920+
let v_d = vec_unique.slice(1u, 6u).to_vec();
909921
assert_eq!(v_d.len(), 5u);
910922
let v_d = v_d.as_slice();
911923
assert_eq!(v_d[0], 2);
@@ -1132,7 +1144,7 @@ mod tests {
11321144
let (min_size, max_opt) = it.size_hint();
11331145
assert_eq!(min_size, 1);
11341146
assert_eq!(max_opt.unwrap(), 1);
1135-
assert_eq!(it.next(), Some(v.as_slice().to_owned()));
1147+
assert_eq!(it.next(), Some(v.as_slice().to_vec()));
11361148
assert_eq!(it.next(), None);
11371149
}
11381150
{
@@ -1141,7 +1153,7 @@ mod tests {
11411153
let (min_size, max_opt) = it.size_hint();
11421154
assert_eq!(min_size, 1);
11431155
assert_eq!(max_opt.unwrap(), 1);
1144-
assert_eq!(it.next(), Some(v.as_slice().to_owned()));
1156+
assert_eq!(it.next(), Some(v.as_slice().to_vec()));
11451157
assert_eq!(it.next(), None);
11461158
}
11471159
{

branches/auto/src/libcollections/str.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ other languages.
5555
5656
# Representation
5757
58-
Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
59-
stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
60-
encoded UTF-8 sequences. Additionally, strings are not null-terminated
61-
and can contain null codepoints.
58+
Rust's string type, `str`, is a sequence of unicode scalar values encoded as a
59+
stream of UTF-8 bytes. All strings are guaranteed to be validly encoded UTF-8
60+
sequences. Additionally, strings are not null-terminated and can contain null
61+
bytes.
6262
6363
The actual representation of strings have direct mappings to vectors: `&str`
6464
is the same as `&[u8]`.

branches/auto/src/libcollections/vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,8 @@ impl<T> Collection for Vec<T> {
437437
}
438438

439439
impl<T: Clone> CloneableVector<T> for Vec<T> {
440-
fn to_owned(&self) -> Vec<T> { self.clone() }
441-
fn into_owned(self) -> Vec<T> { self }
440+
fn to_vec(&self) -> Vec<T> { self.clone() }
441+
fn into_vec(self) -> Vec<T> { self }
442442
}
443443

444444
// FIXME: #13996: need a way to mark the return value as `noalias`

branches/auto/src/libcore/ops.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,19 +749,23 @@ pub trait DerefMut<Result>: Deref<Result> {
749749
#[lang="fn"]
750750
pub trait Fn<Args,Result> {
751751
/// This is called when the call operator is used.
752+
#[rust_call_abi_hack]
752753
fn call(&self, args: Args) -> Result;
753754
}
754755

755756
/// A version of the call operator that takes a mutable receiver.
756757
#[lang="fn_mut"]
757758
pub trait FnMut<Args,Result> {
758759
/// This is called when the call operator is used.
760+
#[rust_call_abi_hack]
759761
fn call_mut(&mut self, args: Args) -> Result;
760762
}
761763

762764
/// A version of the call operator that takes a by-value receiver.
763765
#[lang="fn_once"]
764766
pub trait FnOnce<Args,Result> {
765767
/// This is called when the call operator is used.
768+
#[rust_call_abi_hack]
766769
fn call_once(self, args: Args) -> Result;
767770
}
771+

branches/auto/src/libcore/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub use ops::{BitAnd, BitOr, BitXor};
3535
pub use ops::{Drop, Deref, DerefMut};
3636
pub use ops::{Shl, Shr};
3737
pub use ops::{Index, IndexMut};
38+
pub use ops::{Fn, FnMut, FnOnce};
3839
pub use option::{Option, Some, None};
3940
pub use result::{Result, Ok, Err};
4041

branches/auto/src/libgraphviz/maybe_owned_vec.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,23 +124,23 @@ impl<'a,T:fmt::Show> fmt::Show for MaybeOwnedVector<'a,T> {
124124

125125
impl<'a,T:Clone> CloneableVector<T> for MaybeOwnedVector<'a,T> {
126126
/// Returns a copy of `self`.
127-
fn to_owned(&self) -> Vec<T> {
128-
self.as_slice().to_owned()
127+
fn to_vec(&self) -> Vec<T> {
128+
self.as_slice().to_vec()
129129
}
130130

131131
/// Convert `self` into an owned slice, not making a copy if possible.
132-
fn into_owned(self) -> Vec<T> {
132+
fn into_vec(self) -> Vec<T> {
133133
match self {
134-
Growable(v) => v.as_slice().to_owned(),
135-
Borrowed(v) => v.to_owned(),
134+
Growable(v) => v.as_slice().to_vec(),
135+
Borrowed(v) => v.to_vec(),
136136
}
137137
}
138138
}
139139

140140
impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> {
141141
fn clone(&self) -> MaybeOwnedVector<'a, T> {
142142
match *self {
143-
Growable(ref v) => Growable(v.to_owned()),
143+
Growable(ref v) => Growable(v.to_vec()),
144144
Borrowed(v) => Borrowed(v)
145145
}
146146
}

0 commit comments

Comments
 (0)