What is [String] and how to create it?

One of the function in my project receives Option<&[String]> as one of the argument . If I pass something like Some(&String) or Some( &str) to this function creating compile time error. so what is [String] and how to create it?

[String] is a slice of strings: some number of them. If you want to pass one string, put it in an array, then take a reference to the array, which will coerce to a reference to a slice.

    let string: String = String::from("hi");
    let string_array: [String; 1] = [string];
    let slice_reference_in_option: Option<&[String]> = Some(&string_array);

Example more concisely in a function call:

    foo(Some(&[String::from("hi")]));

The type [T] is called a slice. A slice is an unsized type, which means that its size is not known at compile-time (after all, it could have any length). For this reason, it can only exist behind a reference or smart pointer.

You can create a reference to a slice in many ways. For example, a &Vec<T> can be converted to &[T] using the Vec::as_slice method. Furthermore, due to the Deref trait, a &Vec<T> is automatically converted into a &[T] if you attempt to use a &Vec<T> somewhere that requires an &[T]. As @kpreid points out, a reference to a slice may also point into an array, or any other type that stores several values consecutively in memory.

This way of using the Deref trait is also the reason why you can pass a &String to functions that require a &str, without needing to explicitly call String::as_str.

2 Likes

Here a dummy example on (one way of) how to create it (and use it):

fn foo(x: &[String]) {
    for s in x {
        println!("{s}");
    }
    for s in x {
        println!("Capacity: {}", s.capacity());
    }
}

fn main() {
    let strings = vec!["Hello".to_string(), "World".to_string()];
    foo(&strings);
}

(Playground)

Output:

Hello
World
Capacity: 5
Capacity: 5

1 Like