我们拿 rust rustling 的练习拿来做例子。如果大家不懂Rust语法,也可以通过这些例子来学下语法。
例子1:
原题:
fn main() {
x = 5;
println!("x has the value {}", x);
}
修改后:
fn main() {
let x = 5;
println!("x has the value {}", x);
}
Rust的变量定义使用let, let创建的变量为绑定,let x=5指的是把x和5创建了一种关联关系 。
扩展: Rust中常量为什么用let不用const,变量用let mut不用var?
放到r2上自动分析一下。

用Cutter带的Ghidra反编译器试试:


看main函数, let x=5; 是把5赋给了一个dword双字节的地址,lea 加载变量的有效地址,然后直接fmt和调用print,注意这里的println!是一个宏。
例子2:
原题:
fn main() {
let x: i32;
if x == 10 {
println!("Ten!");
} else {
println!("Not ten!");
}
}
修改后:
fn main() {
let x: i32 = 5;
if x == 10 {
println!("Ten!");
} else {
println!("Not ten!");
}
}
Rust出于内存安全的考虑,不允许变量未初始化。如果你写了let x=5; Rust编译器会自动推断,但是最好是自己加一下类型,主要是因为推断的类型不一定对。
例子3:
原题:
fn main() {
let x = 3;
println!("Number {}", x);
x = 5; // don't change this line
println!("Number {}", x);
}
修改后:
fn main() {
let mut x = 3;
println!("Number {}", x);
x = 5; // don't change this line
println!("Number {}", x);
}
Rust不允许重复赋值,因为默认变量不可变。 需要加mut来变成可变的变量。
不可变绑定和可变绑定的区别:
问题: 为什么要设计默认变量是不可变的?
例子4:
原题:
fn main() {
let x: i32;
println!("Number {}", x);
}
修改后:
fn main() {
let x: i32 = 0;
println!("Number {}", x);
}
也是未初始化的问题
例子5:
原题:
fn main() {
let number = "T-H-R-E-E"; // don't change this line
println!("Spell a Number : {}", number);
number = 3;
println!("Number plus two is : {}", number + 2);
}
修改后:
fn main() {
let number = "T-H-R-E-E"; // don't change this line
println!("Spell a Number : {}", number);
let number = 3;
println!("Number plus two is : {}", number + 2);
}
第一个number 是不可变的字符串类型,然后下面的赋值 number=3是一个整型,肯定不对。需要重新绑定number,把number改为整型并赋值为3
例子6:
原题:
const NUMBER = 3;
fn main() {
println!("Number {}", NUMBER);
}
修改后:
const NUMBER: i32 = 3;
fn main() {
println!("Number {}", NUMBER);
}
Rust的常量必须加类型。那为什么常量不推导呢? 这是因为故意这样设计的,指定类型就不会因为自动推导类型出问题。
扩展: Why is type declaration necessary in constants?


Rust的常量是全局的,而是自动内联的。 如果我们把const 换成static,那么它会被存储在静态存储区中,有一个固定的内存地址,而且不会被内联。
我们来试试:

