String Array, Vector ExamplesCreate and loop over arrays of type str and String. Use string vectors to add strings to a collection.
This page was last reviewed on Oct 7, 2022.
String array. In Rust we often need to use fixed-sized collections of strings. We can use the str primitive type, or the growable String type.
Shows a string arrayShows a string arrayShows an arrayShows a string vec
Initialization syntax. To initialize the array, we can use an initializer expression. If we want growable strings, we may need the to_string function.
Initialize Array
Str example. To begin, we use the str primitive type in this example. String literals are of type str—they cannot grow dynamically.
Part 1 We create a primitive string array of length 2. The elements "bird" and "frog" are added to the array at creation time.
Part 2 We use a for-loop over the animals array. We access each element and print it with println.
Part 3 We mutate the array (which was specified with the mut keyword) and then print the elements again.
Shows a string array
fn main() { // Part 1: create string array. let mut animals: [&str; 2] = ["bird", "frog"]; // Part 2: loop over elements in string array. for animal in &animals { println!("For: {}", animal); } // Part 3: change element in string array. animals[0] = "cat"; println!("Element 0: {}", animals[0]); println!("Element 1: {}", animals[1]); }
For: bird For: frog Element 0: cat Element 1: frog
Growable String array. To create an array of growable strings, we can use the String type, and then call to_string() on string literals. These Strings can be appended to in-place.
Part A We create the String array with an initializer expression. We call to_string() on each element in the initialization.
Part B We use a for-loop over the colors array, and print each element with a println function call.
Shows a string array
fn main() { // Part A: create array of type String. // ... Use to_string for elements. let colors: [String; 2] = ["red".to_string(), "blue".to_string()]; // Part B: print elements. for value in &colors { println!("For: {}", value); } }
For: red For: blue
Iter loop. For string arrays, we can use iter() to loop over the array elements. Here we have an array of ID string literals, and we use iter to iterate them.
Tip In this program we could omit the iter() call as well as the type of the "ids" array—the program would still be the same.
Shows an array
fn main() { let ids: [&str; 3] = ["x100", "y200", "z300"]; // Loop over the array by calling iter() which returns a slice. for value in ids.iter() { println!("ITER: {}", value); } }
ITER: x100 ITER: y200 ITER: z300
String Vec. Sometimes we want to create a collection of strings that we can add to—a string Vec is ideal here. We create the vector with vec, and then can push items to the collection.
Info We use the "vec!" macro to initialize the Vec with 2 str primitives. Then we call push() to add 2 more strings.
Mut We must specify the mut keyword for a mutable vector: this allows us to change it by calling push().
Shows a string vec
fn main() { let mut places = vec!["Paris", "New York"]; places.push("Madrid"); places.push("Toronto"); for place in &places { println!("PLACE: {}", place) } }
PLACE: Paris PLACE: New York PLACE: Madrid PLACE: Toronto
Array argument. We often need to pass arrays as arguments to functions. To receive an array argument, we specify its type in the formal parameter list.
Test The test() fn receives a 2-element str primitive array. It prints the length when in the function body.
fn test(values: [&str; 2]) { // Receive string array as argument, print its length. println!("Length: {}", values.len()); } fn main() { let vegetables: [&str; 2] = ["carrot", "turnip"]; test(vegetables); }
Length: 2
Vector argument. In the modify_vec function, we pass a mutable reference to a string vector. So we can modify the vector in the called function (and the program compiles).
Note By passing a Vec as an argument, we can append many values to a vector (like bytes from a string) in a function.
push u8 Vec
fn modify_vec(values: &mut Vec<&str>) { // Modify the string vector argument. values.push("bird"); } fn main() { let mut animals = vec!["dog"]; // Pass a mut reference to allow vector to be modified in another function. modify_vec(&mut animals); println!("RESULT: {:#?}", animals); }
RESULT: [ "dog", "bird", ]
Get element. How can we get an element from a String vector? We can use the get() function, which returns an Option. If the index is in-range, the element is returned.
Tip We can use the if-let syntax to get the inner value of the option as a local variable (here we call it "first").
fn main() { // 1-element string vec. let mut values = vec![String::from("cat")]; // Use get on an element in the string vector. if let Some(first) = values.get(0) { println!("FIRST: {first}"); } // If the index is out of range, no panic occurs. if let Some(test) = values.get(400) { // Not reached. } }
FIRST: cat
Convert array, vector. We can convert arrays and vectors to slices and use them in a unified way. Here the test() function receives a string slice.
Part A We create a string vector, and then call as_slice() to use the vector as a string slice argument.
Part B We create an array. Then we borrow the array and pass it to the test function as a slice.
Part C We create an array here too, but borrow it in the same statement as a slice. We pass the variable as a slice.
fn test(values: &[&str]) { println!("SLICE LEN: {}", values.len()) } fn main() { // Part A: use as_slice to convert Vector to slice. let shapes = vec!["square", "circle"]; test(shapes.as_slice()); // Part B: use array as slice argument. let shapes2: [&str; 2] = ["square", "circle"]; test(&shapes2); // Part C: get slice from array, and pass as argument. let shapes3: &[&str] = &["square", "circle"]; test(shapes3); }
Split, Vec. We can place the results of the split() function into a String vector with collect(). Here we get a String vector from split and then pretty-print the results.
fn main() { let test = "abc def"; // Call split, and use collect() to get a string Vec. let values: Vec<&str> = test.split(' ').collect(); // Pretty-print the results. println!("VALUES: {:?}", values) }
VALUES: ["abc", "def"]
With capacity. Suppose we know how many Strings we want in a vector. We can provide that number to with_capacity, and then push() the Strings.
Program Here we want to push 100 strings to the vector, so we use with_capacity with an argument of 100.
Tip This is a performance optimization as it reduces allocations and Vec copies if the capacity was too low.
To string In this program, we want a Vec of Strings, not str references, so we call to_string.
Usually In Rust programs using String instead of str is easiest, and we can reduce copying with Arcs.
fn main() { // Create a Vec of Strings, and use a capacity to avoid resizes. let mut birds = Vec::with_capacity(100); for _ in 0..100 { // We call to_string() to have String and not str references. birds.push("bird".to_string()); } println!("Bird count: {}", birds.len()); }
Bird count: 100
Enumerate. Sometimes we want to use a for-in loop over a String Vec or array in Rust. But we may also want the index for some reason.
So We can use enumerate() to get index and element pairs from each position in an array.
Tip This can simplify and improve certain loops in Rust programs. We must use iter() before calling enumerate().
fn main() { let colors = vec!["blue", "green", "yellow"]; // Call enumerate to get index, value pairs in a for-loop. for (i, color) in colors.iter().enumerate() { println!("INDEX = {}, COLOR = {}", i, color); } }
INDEX = 0, COLOR = blue INDEX = 1, COLOR = green INDEX = 2, COLOR = yellow
Repeated, empty. We can create a vector of a single string repeated many times—think of this as a default value string vector. The second "vec" macro argument is the repeat count.
Clear The example also shows how to clear a string vector, which leaves its length as 0, so the is_empty() function will return true.
fn main() { // Create a string vector of 5 repeated strings. let mut repeated_values = vec!["A123".to_string(); 5]; println!("{:?}", repeated_values); // Clear the vector. repeated_values.clear(); println!("{:?}", repeated_values); // See if the vector is empty. if repeated_values.is_empty() { println!("IS EMPTY"); } }
["A123", "A123", "A123", "A123", "A123"] [] IS EMPTY
Convert HashMap, Vec. Often in Rust we have a string array (a String Vec) and want to convert back and forth from HashMap. This can be done using the HashMap from_iter method.
Convert HashMap, vec
A summary. To create string arrays, we can use array syntax like any other array in Rust. But we must choose between string primitives (str) and Strings. Strings are more usable.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Oct 7, 2022 (new example).
© 2007-2022 Sam Allen.