Variables, types, and mutability

A variable is a named box in which a data value can be stored. The variable itself isn't the data value, just like a carton of milk is not the same thing as milk (it's waxed cardboard and such containing milk).

On the other hand, if somebody needs milk and you hand them a full milk carton, they're not going to complain, and the same goes for Rust. If a Rust expression needs an integer, and we provide a variable containing an integer, Rust will be perfectly happy with that.

Variables are most often created using the let keyword:

let x = 10;

This statement creates a variable called x containing the 10 value in it. Once that's done, we can refer to x as part of the expressions. For example, x + 5 is now a valid expression, with a resulting value of 15.

The names that for loops use are also variables, as are function parameters, although they are not created with the let keyword.

In addition to having a name, variables are characterized by the type of value they can store. Each variable can store one kind of value, and can never store any other type of information. Rust can often figure out what type of information a given variable can store, but we always have the option of being explicit about it. If we tell Rust that let x: i32 = 99;then Rust will make sure that the x variable can store a 32-bit signed integer and report an error if we try to store something else there. On the other hand, let x: f64 = 999.0;tells Rust that we want x to store a 64-bit floating-point number and that trying to store anything else there is an error.

We don't have to provide an initial value for a variable. For example, we could say let x: u16;to tell Rust that the x variable needs to be able to store 16-bit unsigned integers. That's fine. However, if it's even possible that some of our code will try to use the contents of the variable without first having stored some contents there to be used, the Rust compiler will consider that an error. It's usually easier to just provide a starting value when we create a variable.

Variables are called variables because the values they contain can be changed. Except in Rust, by default, they can't. Rust allows us to use multiple let statements to create new variables with the same names as old variables, but we can't just assign a new value to an existing variable, unless that variable is mutable.

Creating a new variable with the same name as an existing variable is called shadowing the old variable. A shadowed variable still contains the value it did before, but cannot be accessed by name any more, because that name now belongs to a different variable. If there are any references to the old variable still in play, they will still be accessing the old variable, though, not the new one.

Being mutable just means that the variable will accept changes, up to and including a whole new value. We use the mut keyword to tell Rust that a variable should be mutable:

let mut x = 17;

The new x variable is mutable. That means we can modify its contents:

x = 0;

Instead of containing 17, x now contains 0.

The equal symbol (=) that we're using for variables is not a statement of mathematical equality. It doesn't mean: These two things are defined as being the same. Instead it means: Right here, right now, the value produced by the expression on the right side of the = is to be stored in the variable on the left. This would be nonsense in math, but it makes perfect sense in Rust:

for i in 0..5 {
x = x + i;
}

Rust has quite a lot of built-in data types. We've seen i32, f64, and u16, which are 32-bit signed integer, 64-bit floating point, and 16-bit unsigned integer, respectively. There are also more types following the same pattern, such as u64 for an unsigned 64-bit integer, as well as types such as bool for Boolean values; isize and usize for signed and unsigned integers that take up the same number of bits as a memory address on the target architecture; and char and str for single Unicode code points and sequences of them.

These are known as primitive types, because they're inherent to the language. However, Rust also allows us to create new types, and so the Rust standard library contains many more data types that are suited to various specific uses, and there are even more available in third-party libraries.

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

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