about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2014-08-28 14:05:33 -0400
committerSteve Klabnik <steve@steveklabnik.com>2014-09-09 18:48:30 -0400
commit8ddb9c71c3f4c18a2679d498d5fe65a9b6516270 (patch)
tree107a1fe8378fb7245082cd900e2ebad4fc33fd72
parentbda3ceda039f0d37c726ca62e0bac457ce39d071 (diff)
downloadrust-8ddb9c71c3f4c18a2679d498d5fe65a9b6516270.tar.gz
rust-8ddb9c71c3f4c18a2679d498d5fe65a9b6516270.zip
Add section about Str trait
-rw-r--r--src/doc/guide-strings.md37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/doc/guide-strings.md b/src/doc/guide-strings.md
index bf762d13b78..a49132ec8be 100644
--- a/src/doc/guide-strings.md
+++ b/src/doc/guide-strings.md
@@ -92,9 +92,33 @@ fn foo(s: String) {
 ```
 
 If you have good reason. It's not polite to hold on to ownership you don't
-need, and it can make your lifetimes more complex. Furthermore, you can pass
-either kind of string into `foo` by using `.as_slice()` on any `String` you
-need to pass in, so the `&str` version is more flexible.
+need, and it can make your lifetimes more complex.
+
+## Generic functions
+
+To write a function that's generic over types of strings, use [the `Str`
+trait](http://doc.rust-lang.org/std/str/trait.Str.html):
+
+```{rust}
+fn some_string_length<T: Str>(x: T) -> uint {
+        x.as_slice().len()
+}
+
+fn main() {
+    let s = "Hello, world";
+
+    println!("{}", some_string_length(s));
+
+    let s = "Hello, world".to_string();
+
+    println!("{}", some_string_length(s));
+}
+```
+
+Both of these lines will print `12`. 
+
+The only method that the `Str` trait has is `as_slice()`, which gives you
+access to a `&str` value from the underlying string.
 
 ## Comparisons
 
@@ -134,7 +158,7 @@ println!("{}", s[0]);
 
 This does not compile. This is on purpose. In the world of UTF-8, direct
 indexing is basically never what you want to do. The reason is that each
-charater can be a variable number of bytes. This means that you have to iterate
+character can be a variable number of bytes. This means that you have to iterate
 through the characters anyway, which is a O(n) operation. 
 
 To iterate over a string, use the `graphemes()` method on `&str`:
@@ -147,6 +171,9 @@ for l in s.graphemes(true) {
 }
 ```
 
+Note that `l` has the type `&str` here, since a single grapheme can consist of
+multiple codepoints, so a `char` wouldn't be appropriate.
+
 This will print out each character in turn, as you'd expect: first "α", then
 "ἰ", etc. You can see that this is different than just the individual bytes.
 Here's a version that prints out each byte:
@@ -154,7 +181,7 @@ Here's a version that prints out each byte:
 ```{rust}
 let s = "αἰθήρ";
 
-for l in s.as_bytes().iter() {
+for l in s.bytes() {
     println!("{}", l);
 }
 ```