Variables in Rust are similar to variables in other high-level programming languages, and how we declare and use them is pretty straightforward. There are several types of variables, and their declaration may differ from each other.
Types Of Variables In Rust
A variable can be a global variable, a local variable, a function parameter, or a struct field. As such, its declaration may require initialization at the same time.
Global Variable
A variable is a global variable when we declare it outside of any code blocks with the static keyword. We need to specify the data type and value when we declare the variable.
1 2 | // Outside of any code block static my_age: i32 = 30; |
Local Variable
If we declare it inside a function, it is typically a local variable, and the data type may be optional in Rust.
1 2 3 4 5 6 7 | fn main() { // Data type is optional let my_age = 30; // Explicitly specified data type let my_secret_number: i32 = 19; } |
It can also be part of a for loop. In this case, we cannot specify its data type.
1 2 3 4 5 | fn main() { for counter in [1, 2].iter() { println!("{}", counter) } } |
Function Parameter
If we declare a variable as part of a Rust function definition, it is a function parameter. We need to specify its data type.
1 2 3 | fn process_my_age(param_my_age: i32) { println!("{}", param_my_age); } |
Struct Field
A variable declared in a struct is a struct field. We only need to specify its data type. However, when we instantiate the struct Person, we need to specify appropriate values for the fields
1 2 3 4 | struct Person { name: String, age: i32 } |
Declare A Variable With a Valid Name
When naming a variable, we can use letters, digits, and the underscore character. However, it must start with either a letter or an underscore. Moreover, a variable name with lowercase letters differs from a variable with uppercase letters because Rust is case-sensitive.
There are some restrictions on variable names in Rust.
- We must begin variable names with a letter or underscore (_) character.
- We can only use letters, numbers, and the underscore character for variable names.
- Variable names are case-sensitive, so my_variable and my_Variable are considered two different variables.
Consider the following examples of valid and invalid variable names in Rust:
- my_variable (valid)
- myVariable1 (valid)
- _myVariable (valid)
- my-variable (invalid – cannot contain hyphens)
- let (invalid – cannot be a reserved keyword)
- 1myVariable (invalid – must begin with a letter or underscore)
Declare And Assign Value In Rust
A variable in Rust can have an initial value when we declare it. But it depends on where we declare and how we use the variable. We can also assign it value after the declaration, depending on whether it is a mutable or immutable variable. By default, all variables are immutable in Rust.
For instance, these codes will fail compilation.
1 2 3 4 | fn main() { let my_age= 30; my_age = 40; } |
1 2 3 4 5 6 7 8 9 10 | error[E0384]: cannot assign twice to immutable variable `my_age` --> src\main.rs:3:5 | 2 | let my_age= 30; | ------ | | | first assignment to `my_age` | help: make this binding mutable: `mut my_age` 3 | my_age = 40; | ^^^^^^^^^^^ cannot assign twice to immutable variable |
To declare a mutable variable in Rust, we use the mut keyword.
1 2 3 4 | fn main() { let mut my_age= 30; my_age = 40; } |
Using Variables
Although not immediately apparent when using Rust’s scalar primitive types, values have ownership and can change owners – from one variable to another. For example, these codes build and run successfully:
1 2 3 4 5 6 7 | fn main() { let a: i32 = 3; let b: i32 = a; println!("a={}", a); println!("b={}", b); } |
However, these will not compile:
1 2 3 4 5 6 7 8 9 10 | struct MyOwnI32 { // Just an empty struct } fn main() { let a: MyOwnI32 = MyOwnI32 {}; let b: MyOwnI32 = a; let c: MyOwnI32 = a; } |
1 2 3 4 5 6 7 8 9 10 | error[E0382]: use of moved value: `a` --> src\main.rs:9:24 | 6 | let a: MyOwnI32 = MyOwnI32 {}; | - move occurs because `a` has type `MyOwnI32`, which does not implement the `Copy` trait 7 | let b: MyOwnI32 = a; | - value moved here 8 | 9 | let c: MyOwnI32 = a; | ^ value used here after move |
Declaring and using variables is pretty straightforward until we start using custom data types. Then, we will have to deal with ownership and lifetimes.
This post is now part of the Rust Programming Language For Beginners Tutorial.