- In this section we're going to look
at string handling in Rust.
And it turns to be a bit more complicated
than you might imagine.
It turns out there are two different kinds
of string in Rust, and the first type is a string literal,
where you just literally have some text enclosed
inside double quotes, like that,
that's a string literal
String literals are statically allocated.
The text is part of your program forever
but you can't change it.
It's immutable, so it's not very flexible.
If you want flexibility and potentially to change
or resize a string, then you can create an instance
of the string type.
String is a structure in Rust and represents
dynamically allocated memory.
The text is actually allocated on the heap.
You can potentially change it
if you declare your string object as mutable
and when your string object disappears,
when it goes outta scope,
then the text is dynamically de-allocated.
So this string structure in Rust
is kind of similar to the string class in C++.
When you create an instance of the string class,
when you create a string object,
the memory is allocated on the heap like so
and you can potentially change it if you want to
as long as you declared the string as mutable.
You could, for example, append something at the end
like this, my name and the O like that.
And at the end of the lifetime
when the string object is destroyed,
it automatically de-allocates its memory like that.
Effectively there's an equivalent of a distractor
in the string class to de-allocate its buffer.
So we need to look at both of these two types separately.
String literals first.
So a string literal is literally text
enclosed in double quotes, okay?
So that seems quite straightforward.
You might be wondering what type is S
and it turns out to be a bit complicated.
When you declare a variable to hold a string literal,
the variable is a string slice, okay?
So str is a primitive type in Rust and the ampersand,
when you say ampersand str,
when you look at that bit of the syntax,
I'll explain the static bit in a minute.
When you see ampersand str,
basically that's called a string slice.
A string slice is sometimes called a fat pointer.
Underneath the surface, the text
that we're trying to refer to is static storage
allocated along the code segment.
And when you declare a string slice like I've done,
either using type inference or when you use explicit typing,
effectively what you get, s, is a string slice.
It has a pointer to the first byte in the text
and it has a count to tell you how big the string is.
There were five characters in hello.
Okay, there's no null terminator at the end of strings
in Rust, they just kind of stop.
So a string slice is a fat pointer.
It points to the first byte
and it knows how many bytes there are.
This bit of syntax here, the quote and the static,
it's called a lifetime specifier.
Rust is very careful about only referring to things
that it knows are still allocated.
You can think of a string slice
as being a bit like a pointer into memory
and Rust needs to know that the memory isn't gonna disappear
before the pointer does.
Imagine that this storage was dynamically allocated
then he'd be left pointing to a dangling pointer.
So this syntax basically says it is basically a string slice
to static storage, okay?
Meaning that the memory that you're pointing to
is statically allocated and will always be there.
You can always guarantee that the underlying text
will be there,
so that means you can always rely on this slice
always pointing to a valid address in memory.
So there we are.
I did say it was gonna be a bit complicated, didn't I?
So anyway, a string slice in essence
is that the ampersand str syntax is a string slice.
It contains the pointer to the text
and it knows how many bytes there are in the text, okay?
So that's basically the type of a string literal
in Rust is a static string slice.
Right, so a string slice knows the address
of the first byte and it knows the number of bytes.
And it turns out if you looked at the documentation
for str online, you'd find out that the str type
has an as pointer method.
It'll basically give you the pointer,
it'll give you the address of the first byte.
It also has a length method,
which gives you the length in bytes of the string like so.
So have a look at this bit of code
in my bottom yellow box here.
You can output.
If you output a string, a string slice I should say,
it outputs hello.
If you call the as pointer function,
it gives you back the address.
You've gotta print that address using the print, sorry,
the pointer formatter.
The colon P syntax means print out an address as a pointer.
It'll actually print out an address as a pointer.
And then finally I print out the length of the string.
The length of the string here would be five.
I'm gonna show you an example of this
before we go any further.
Here's the code example, lesson six, scope ownership.
In the main code, I've got a function call
demo string handling.
I've commented it.
String handling is here and in this example
I've got three separate parts to the demo.
A demo of string literals, first of all, and I'm gonna call,
I've got two other functions here
using string objects and using mutable string objects.
We'll come to those later.
We'll just have a look at string literals first
and I'm gonna comment out these other two statements.
So here is a string literal using type inference.
Here is another string literal
using explicit typing if you want to.
And here I output string one.
I get the address of the text of the slice.
Basically that's the address of the letter H as a pointer.
And I get the length of s1, that's going to be five.
And then I do the same thing for s2,
to print out the contents of s2,
the address where the string starts in memory as pointer
and then the length of the string s2 dot length.
Okay, so let's run this.
Cargo run,
so it outputs s1 is hello.
Okay, so that's just basically printed out
the string slice as it is.
Get the address of the first byte in s1
and gimme the length of s1 in bytes.
And then the same thing for the second string slice, s2.
Okay, so basically when you have a string literal,
technically it is a string slice.
It knows the address and the length
of the text that it's pointing to.