Variables and Functions
variable
The default value of a variable is immutable. Called a variable but immutable:
let x = 5;
println!("{}", x); / / 5
x = 6; // error: x is immutable
Copy the code
Use the muT keyword to make variables variable:
let mut y = 5;
println!("{}", y); / / 5
y = 6; // Add muT
println!("{}", y); / / 6
Copy the code
Variables allow repeated definitions, overwriting the previous definition:
let z = 5;
println!("{}", z); / / 5
let z = 6; // repeat the definition
println!("{}", z); / / 6
// Allow to change the last type
let spaces = "123";
let spaces = spaces.len(); // Change from &str to usize
println!("{}", spaces); / / 3
// Mut can only change the value of a variable, not the type
let mut spaces2 = "123";
spaces2 = spaces2.len() // An error was reported, expecting a & STR, but getting a usize
Copy the code
Constants are defined using the const keyword, all uppercase, and explicitly indicating the data type:
const YEAR: u32 = 365;
println!("{}", YEAR); / / 365
Copy the code
Use destructuring to define variables
Deconstructing a member from an array:
let arr = [1.2.3];
let [a, b, c] = arr;
println!("{} - {} - {}", a, b, c); / / 1-2-3
// An error will be reported if only part of the member is destructed
let [a,b] = arr; // An error was reported, expecting to deconstruct 3 members
/ / to use.. To omit unwanted members
let[a, b, ..] = arr;Copy the code
Deconstructing members from tuples:
let tuple = (1."2".3.5);
let (a, b, c) = tuple;
println!("{} - {} - {}", a, b, c);
// All members of a tuple must also be constructed
let (a, b) = tuple; // An error was reported, expecting to deconstruct 3 members
/ / to use.. To omit unwanted members
let (a, b, ..) = tuple;
Copy the code
To deconstruct a property from a structure, we can first understand the structure as an object in JS:
// Declare a structure of type User
struct User {
name: String,
age: u8,}// Define a xiao_ming variable, which is the User structure type
let xiao_ming = User {
name: "xiaoming".to_string(),
age: 18
};
// All of them
let User { name, age } = xiao_ming;
println!("name:{} age:{}", name, age); // name:xiaoming age:18
// For the deconstruction part, we still need to make sure that the left pattern is consistent with the structure
let User { age } = xiao_ming; // The pattern on the left does not match the structure on the right. Age is missing
/ / to use.. To omit unwanted members
let User { age, .. } = xiao_ming;
println!("age:{}", age); / / 18
Copy the code
Enumeration structure members, you can learn a little about enumeration, which will be described in the following sections:
// Define an enumeration type: Ip
enum Ip {
// Contains a "variant" of String: V4
V4(String)}// Define a variable of type Ip::V4 (double colons can be understood as ". ) contains the value "127.0.0.1"
let localhost = Ip::V4(String::from("127.0.0.1"));
// When the enumeration has only one type, we can destruct it directly. Let is the mode, and IP in parentheses is the destructed variable
let Ip::V4(ip) = localhost;
println!("{}", ip); / / 127.0.0.1
// Destructuring enumerations with multiple types will cause an error
enum Ip {
V4(String),
V6(String)}let Ip::V4(ip) = localhost; // An error was reported because localhost might be of type V6
// Use an if let to override multiple types
if let Ip::V4(ip) = localhost {
println!("V4: {}", ip); / / 127.0.0.1
} else if let Ip::V6(ip) = localhost {
println!("V6: {}", ip);
} else {
println!("other");
}
Copy the code
function
Functions are defined using the keyword fn, named snake Case, and separated by underscores:
fn fn_name() {
println!("fn_name called");
}
Copy the code
Call a function:
foo();
Copy the code
Function arguments are distinguished in technical documentation in two ways: parameter indicates the parameter and argument indicates the argument, but we generally do not distinguish. The type of function argument must be explicitly stated:
foo(100); // functions are allowed to be called before definition
fn foo(num: i32) {
println!("foo called with: {}", num); // foo called with: 100
}
Copy the code
The type of the return value of a function also needs to be specified explicitly. Use → to indicate the return value type:
// return type I32
fn add_one(num: i32) - >i32 {
return num + 1
}
// The return keyword can be omitted
fn add_two(num: i32) - >i32 {
Num +1 is the return value of the function because there is no other call after num+1
// But do not end with a semicolon
num + 2
}
Copy the code
The return value of the function is actually a tuple:
// return an empty tuple :()
fn foo() {}
// return a tuple with one member :(1)
fn foo2() - >i32 {
return 1
}
let num = foo2();
println!("{}", num); / / 1
// So you can return tuples with multiple members
fn foo4() - > (i32.bool) {
return (1.true)}let res = foo4();
// Print tuples or arrays using :? A placeholder
println!("{:? }", res); // (1, true)
// You can deconstruct the return value
let (num, boo) = foo4();
println!("{} - {}", num, boo); // 1, true
// Deconstructing the return value still requires deconstructing all members
let (num) = foo4(); // An error has been reported. The return value contains two primitives
/ / to use.. To omit unwanted members
let (num, ..) = foo4();
// Since the return value is a tuple, use ". A member that can take the return value
let tup = foo4()
println!("{}", tup.0); / / 1
println!("{}", tup.1); // true
Copy the code
Statements and expressions in the function body
Statements refer to instructions that perform operations but return no value:
// The instruction used to create variables and bind values using the let keyword is a statement
let x = 2;
// let z = 5 is a statement with no return value, so rust does not allow this
let y = (let z = 5); / / an error
Copy the code
An expression is an instruction that evaluates and produces a value as a result:
// Mathematical operations are expressions
1 + 2
// Scope blocks are also expressions
let x = {
let y = 1;
// If you add a semicolon to the end of an expression, it becomes a statement and does not return any value
y + 2
};
println!("{}", x) / / 3
Copy the code