Borrowed strings – &str

We can also have strings as references called string slices. These are denoted by &str (pronounced as stir), which is a reference to a str type. In constrast to the String type, str is a built-in type known to the compiler and is not something from the standard library. String slices are created as &str by default—a pointer to a UTF-8 encoded byte sequence. We cannot create and use values of the bare str type, as it represents a contiguous sequence of UTF-8 encoded bytes with a finite but unknown size. They are technically called unsized types. We'll explain unsized types later in this chapter.

str can only be created as a reference type. Let's assume we try to create a str type forcibly by providing the type signature on the left:

// str_type.rs

fn main() {
let message: str = "Wait, but why ?";
}

We'll be presented with a confusing error:

It says: all local variables must have a statically known size. This basically means that every local variable we define using a let statement needs to have a size as they are allocated on the stack and the stack has a fixed size. As we know, all variable declarations go on the stack either as values themselves or as pointers to heap allocated types. All stack-allocated values need to have a proper size known and, due to this, str cannot be initialized.

str basically means a fixed-sized sequence of strings that's agnostic to the location where it resides. It could either be a reference to a heap-allocated string, or it could be a &'static str string residing on the data segment of the process that lives for the entire duration of the program, which is what the 'static lifetime denotes.

We can, however, create a borrowed version of str, as in &str, which is what gets created by default when we write a string literal. So string slices are only created and used behind a pointer—&str. Being a reference, they also have different lifetimes associated with them based on the scope of their owned variable. One of them is of 'static lifetime, which is the lifetime of string literals.

String literals are any sequence of characters you declare within double quotes. For example, we create them like so:

// borrowed_strings.rs

fn get_str_literal() -> &'static str {
"from function"
}

fn main() {
let my_str = "This is borrowed";
let from_func = get_str_literal();
println!("{} {}", my_str, from_func);
}

In the preceding code, we have a get_str_literal function that returns a string literal. We also create a string literal my_str in main. my_str and the string returned by get_str_literal has the type, &'static str. The 'static lifetime annotation denotes that the string stays for the entire duration of the program. The & prefix says that it's a pointer to the string literal, while str is the unsized type. Any other &str type you encounter are borrowed string slices of any owned String type on the heap. The &str types, once created, can't be modified as they are created immutable by default.

We can also take a mutable slice to the string, and the type changes to &mut str, though it's uncommon to use them in this form except with a few methods in the standard library. The &str type is the recommended type to be used when passing strings around, either to functions or to other variables.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset