Chapter 08¶
HashMap¶
Hash Map: all of the keys must have the same type as each other, and all of the values must have the same type
String¶
Rust strings don’t support indexing. A String is a wrapper over a Vec\<u8>.
String Literal¶
"Hello there." is a string literal and its type is &'static str. A string literal is a string slice that is statically allocated, meaning that it’s saved inside our compiled program, and exists for the entire duration it runs.
Differences between &str and String¶
- Unlike String, which is an owned, heap-allocated string, string slices are references and do not own the data they point to.
- String slices have a fixed size determined at compile time, making them more efficient for certain use cases.
Creation of &str¶
-
String slices can be created from string literals, owned String instances, or other string slices.
-
String literals are automatically coerced to &str when used in contexts expecting a reference.
or
Concatenation with the + Operator or the format! Macro¶
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
The string s3 will contain Hello, world!. The reason s1 is no longer
valid after the addition, and the reason we used a reference to s2, has to do
with the signature of the method that’s called when we use the + operator.
The + operator uses the add method, whose signature looks something like
this:
The reason we’re able to use &s2 in the call to add is that the compiler
can coerce the &String argument into a &str. When we call the add
method, Rust uses a deref coercion, which here turns &s2 into &s2[..].
We’ll discuss deref coercion in more depth in Chapter 15. Because add does
not take ownership of the s parameter, s2 will still be a valid String
after this operation.
Difference of "&str" and "String"¶
&stris a borrowed string slice that points to existing string data.Stringis an owned, heap-allocated string that can be modified and resized.
fn main() {
// String slice (&str) - Immutable reference to a string literal
let str_slice: &str = "hello";
// String (owned) - Dynamically allocated, mutable string
let mut owned_string: String = String::from("world");
// Append to the owned string
owned_string.push_str(", Rust!");
println!("{}", str_slice); // Prints: hello
println!("{}", owned_string); // Prints: world, Rust!
}
Bytes and Scalar Values and Grapheme Clusters! Oh My!¶
Another point about UTF-8 is that there are actually three relevant ways to look at strings from Rust’s perspective: as bytes, scalar values, and grapheme clusters (the closest thing to what we would call letters).