Substring. In Rust we often need to extract a certain range of characters from a string. We want the first 2 characters, or the last several characters.
Slice notes. No substring() function is available directly in Rust, but we can take slices or use the get() function. These functions take substrings.
Slice, get. To begin, we have a Rust program that introduces a short string literal. We want to take the middle 2 chars of the string "bird."
Version 1 We access the slice starting at index 1, and continuing to index 3. So we get characters at 2 and 3.
Version 2 We access the same substring, but use the get() function and unwrap its result. The result is the same.
fn main() {
let value = "bird";
// Version 1: use slice syntax to take substring.
let result1 = &value[1..3];
println!("SUBSTRING: {}", result1);
// Version 2: use get() to take substring.
let result2 = value.get(1..3).unwrap();
println!("SUBSTRING: {}", result2);
}SUBSTRING: ir
SUBSTRING: ir
First, last parts. We can omit the first or last index from the slice syntax. If we omit an index, it is assumed to be either the first or last possible index.
Note If we omit the first, the slice starts at the first possible character. This "pins" the slice to the start.
Note 2 If we omit the last, the slice continues until no more characters are available.
Here This Rust program takes the first 2 characters. To take the last 2, it uses len() to count back 2 from the total string length.
fn main() {
let value = "abcdef";
// Get first 2 characters.
let result1 = &value[..2];
println!("SUBSTRING: {}", result1);
// Get last 2 characters.
let result1 = &value[value.len()-2..];
println!("SUBSTRING: {}", result1);
}SUBSTRING: ab
SUBSTRING: ef
Struct example. In Rust programs, using the String type is often simplest as it indicates ownership. A String owns its own data. To store substrings, we can convert them to Strings.
Result The Result struct has 2 Strings, and it will own the string data in those objects.
Tip Tracking ownership with str references can speed up programs, but in the real world, using Strings and copying is easier.
#[derive(Debug)]
struct Result {
a: String,
b: String
}
fn main() {
let source = "1234".to_string();
let mut part1 = String::new();
let mut part2 = String::new();
// Get left substring.
if let Some(part) = source.get(0..2) {
part1 = part.to_string();
}
// Get right substring.
if let Some(part) = source.get(2..) {
part2 = part.to_string();
}
// Place substrings in struct.
let result = Result{a: part1, b: part2};
println!("{:?}", result);
}Result { a: "12", b: "34" }
From utf8 lossy. Sometimes we may have an array or vector of u8 values (bytes). We can get a String from these values by using from_utf8_lossy.
fn main() {
let data = vec![b'a', b'b', b'c', b'd'];
// If we need a String, not a str, we can use from utf8 lossy.
let result = String::from_utf8_lossy(&data[0..=2]);
println!("{result}");
}abc
A review. Taking substrings in Rust amounts to taking slices and being familiar with slice syntax. The get() function does the same thing as slice, but avoids errors.
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 Nov 10, 2023 (simplify).