rust/src/doc/trpl/strings.md
Kevin Yap 8f61814641 Standardize punctuation & formatting of TRPL
This commit is an attempt to standardize the use of punctuation and
formatting in "The Rust Programming Language" as discussed in #19823.

- Convert bold text to italicized textcwhen referring to terminology.
- Convert single-quoted text to italicized or double-quoted text,
  depending on context.
- Use double quotes only in the case of scare quotes or quotations.
2015-01-08 17:15:26 -08:00

2.4 KiB

% Strings

Strings are an important concept for any programmer to master. Rust's string handling system is a bit different from other languages, due to its systems focus. Any time you have a data structure of variable size, things can get tricky, and strings are a re-sizable data structure. That being said, Rust's strings also work differently than in some other systems languages, such as C.

Let's dig into the details. A string is a sequence of Unicode scalar values encoded as a stream of UTF-8 bytes. All strings are guaranteed to be validly encoded UTF-8 sequences. Additionally, strings are not null-terminated and can contain null bytes.

Rust has two main types of strings: &str and String.

The first kind is a &str. These are called string slices. String literals are of the type &str:

let string = "Hello there."; // string: &str

This string is statically allocated, meaning that it's saved inside our compiled program, and exists for the entire duration it runs. The string binding is a reference to this statically allocated string. String slices have a fixed size, and cannot be mutated.

A String, on the other hand, is an in-memory string. This string is growable, and is also guaranteed to be UTF-8.

let mut s = "Hello".to_string(); // mut s: String
println!("{}", s);

s.push_str(", world.");
println!("{}", s);

You can get a &str view into a String with the as_slice() method:

fn takes_slice(slice: &str) {
    println!("Got: {}", slice);
}

fn main() {
    let s = "Hello".to_string();
    takes_slice(s.as_slice());
}

To compare a String to a constant string, prefer as_slice()...

fn compare(string: String) {
    if string.as_slice() == "Hello" {
        println!("yes");
    }
}

... over to_string():

fn compare(string: String) {
    if string == "Hello".to_string() {
        println!("yes");
    }
}

Viewing a String as a &str is cheap, but converting the &str to a String involves allocating memory. No reason to do that unless you have to!

That's the basics of strings in Rust! They're probably a bit more complicated than you are used to, if you come from a scripting language, but when the low-level details matter, they really matter. Just remember that Strings allocate memory and control their data, while &strs are a reference to another string, and you'll be all set.