Variables#
Variables in Rust are divided into mutable and immutable, which can be compared to the let
and const
declarations in JavaScript. I don't understand why they are still divided into mutable and immutable when they are both called variables. Is it a case of "white horse is not a horse"?
// Declare an immutable variable
let x = 1;
// Declare a mutable variable
let mut y = 1;
mut
is short for mutable, and the first thing you should do when learning syntax is to understand the English meaning of keywords (for Chinese developers). Even if you memorize it, you may forget it easily. With my limited English knowledge, I had to ask chatGPT to find out what this abbreviation stands for. DeepL probably considers it an obscure word and didn't give me a result when translating from Chinese to English.
Constants#
There is no direct equivalent of constants in Rust compared to JavaScript, but if you have to compare, you can compare them to the environment variables in Node.js because they have similar restrictions. Constants cannot be calculated at runtime and are generally used in a global scope.
// This const is not the same as that const
const SOME_CONSTANT: i32 = 10 * 20;
Shadowing#
This feature can also be defined separately, but its practical purpose is to reuse variable names. Of course, the prerequisite is that the hidden variable is no longer needed in the current scope. JS also has this behavior (I made a mistake, in JS, redeclaring with let
will cause an error), and I feel that it is easy to confuse when writing code.
let x = 1;
// This block accesses x as 1
{
// This block still accesses x as 1
let x = x + 1;
// This block accesses x as 2, there is no way to access the previous x as 1
}
// After this block, x is accessed as 1 again
Note that this is not an assignment behavior, but a new declaration of a variable, with the same variable name.
Scalars#
Scalars are similar to primitive types in JavaScript, which means they are individual values, as opposed to composite concepts.
There are four basic scalar types: integers, floating-point numbers, booleans, and characters. These concepts are self-explanatory, but it is worth noting that characters, as scalar descriptors, refer to the char
type in Rust, which represents a Unicode value. In simple terms, it can be a letter, whitespace character, Chinese character, emoji, etc. Additionally, there is a counterintuitive point that integer arithmetic operations in Rust truncate the decimal places.
Compound Types#
Tuples#
Tuples can combine multiple values of different types and are commonly used for function return values. Tuples with zero members are called unit tuples (??not called zero tuples), similar to void
in JavaScript. In Rust, expressions that do not return a value implicitly return a unit tuple.
let tup = (1, 'f', true);
let num = tup.0;
// Destructuring is also possible
let (num, str, bool) = tup;
Arrays#
Arrays in Rust are different from arrays in JavaScript except for the []
syntax. First, arrays in Rust require a fixed length, and second, all members must be of the same type. They are typically used to declare constants that can be exhaustively enumerated, such as the twelve months of the year or the seven days of the week.
let arr = [1, 2, 3];
let first = arr[0];
let last = arr[2];
Enums#
Enums are types that can represent all possible variants. In Rust, enums can contain values of any type. Enums can also define associated functions, which I feel greatly enhance code flexibility.
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
impl Message {
fn call(&self) {}
}
let move = Message::Move { x: 1,y: 2 }
move.call()
[[Structs]]#
Structs are similar to the concept of class
and are collections of multiple related fields.
// Definition
struct User {
name: String,
age: u8,
};
// Instantiation
let user1 = User {
name: String::from("name"),
age: 18,
};