官网:https://www.rust-lang.org/
跟着例子学 Rust:https://tourofrust.com/00_zh-cn.html
Rust 基础入门指南:为 Solana 合约学习铺路 https://learnblockchain.cn/column/113
菜鸟 Rust 教程:https://www.runoob.com/rust/rust-tutorial.html
一、输出到终端
fn main() {
// 输出小图标 =>
println!("你好,🦀!"); // 你好,🦀!
// 占位符输出
let x = 12;
println!("x is {}", x); // x is 12
// 多占位符输出
println!("x is {},{}", x, x); // x is 12,12
// 指定index占位符输出
println!("x is {0},{0}", x); // x is 12,12
// 输出占位符(转义{})
println!("{{}}"); // {}
}
二、变量与常量
类型推断
Rust 是强类型语言,但具有自动判断变量类型的能力。变量的定义使用 let
let a = 1; // 等于 let a: i32 = 1
常用数据类型如下:
fn main() {
// 整数:8位 ~ 128位(8、16、32、64、128)*(有符号i、无符号u)
// 默认为 i:32
let a: i128 = -42; // 有符号整数
let b: u32 = 42; // 无符号整数
// 浮点数:32位、64位 默认为 f64
let c = 2.0; // f64
let d: f32 = 3.0; // f32
// 布尔数
let e = true;
let f: bool = false;
// 字符类型:4字节(32位)
// 采用 Unicode 编码,可以存储更广泛的字符,如表情、数学符号
// 而字符串 String 是多个字符的组合,组成的字符长度可变,每个字符可能占 1-4 字节(UTF-8 编码)
let g: char = 'A';
let h: char = '😃';
let r: char = 'Ω';
let j: char = '∑';
// 元组
// 复合类型,可以将不同类型的多个值组合进一个复合类型
// 结合函数,返回多个不同类型的返回值,很好用
let k: (i32, f32, u8) = (100, 6.4, 1);
// 可以使用 点. 来访问元组的值;也可以用变量接收的方式
let k1 = k.0;
let k2 = k.1;
let (x, y, z) = k;
println!("y is {}", y);
// 数组
// 与元组不同,数组的值必须是同一类型
let a = [1, 2, 3, 4, 5];
let b = ["January", "February", "March"];
let c: [i32; 5] = [1, 2, 3, 4, 5];
let d = [3; 5]; // 等同于 let d = [3, 3, 3, 3, 3];
// 数组访问
let first = a[0];
let second = a[1];
a[0] = 123; // 错误:数组 a 不可变,元素不可重新赋值
let mut a = [1, 2, 3]; // 可变数组
a[0] = 4; // 正确
}
可变性与类型匹配
fn main() {
let a = 1; // 默认不可变
a = 2; // 失败
let mut b = 10; // mut 修饰为可变变量
b = 20; // 成功
b = 20.0; // 失败,类型不匹配
b = "123"; // 失败,类型不匹配
println!("Hello, {},{}", a,b)
}
常量
常量的定义使用 const
const A:i32 = 123;
fn main() {
println!("a is {}", A)
}
三、函数
基本格式:fn <函数名> ( <参数> ) -> 返回类型 <函数体>,如果没有返回,则不需要“-> 返回类型”
fn main() {
// 函数调用方式
let return_value = has_return_value(1, 2);
println!("has_return_value is {}", return_value);
has_no_return_value(1, 2);
has_code_block();
inner_function();
// 函数嵌套
fn inner_function() {
println!("inner_function")
}
}
// 测试返回值,Rust 中定义函数如果需要具备参数必须声明参数名称和类型
fn has_return_value(a: i32, b: i32) -> i32 {
// 以下三种方式相同
return a + b;
// return a + b 不带分号
// a + b 不带分号
}
// 测试没有返回值
fn has_no_return_value(a: i32, b: i32) {
println!("has_no_return_value is {}", a + b);
}
// 测试复杂的表达式块
fn has_code_block() {
let y = {
let x = 1;
x + 2 // 表达式块{}中的返回表达式必须不带分号,不可以使用return关键词,函数的任何地方使用了 return 关键词,就表示函数结束
};
println!("has_code_block is {}", y);
}
四、流程控制
条件语句
if 语句不仅可以用于条件判断,还可以作为表达式返回值
fn main() {
let a = 12;
let b;
// if 语句不需要小括号,Rust 中的条件表达式必须是 bool 类型
if a > 0 {
b = 1;
} else if a < 0 {
b = -1;
} else {
b = 0;
}
println!("b is {}", b);
// 条件语句赋值
let x = 3;
let number = if x > 0 { 1 } else { -1 };
println!("number 为 {}", number);
}
循环语句
for 语句通常用于遍历集合,并且比 while 更安全(避免数组越界),可以使用 continue 跳过本次迭代,break 终止循环。
while 语句在满足条件时执行循环,但可能会导致索引越界错误
loop 适用于需要手动 break 退出的情况,可以结合 break 作为表达式返回值
fn main() {
// while 循环
let mut number = 1;
while number != 4 {
println!("{}", number);
number += 1;
}
// for 循环
let a = [10, 20, 30, 40, 50];
// 迭代器访问
for i in a.iter() {
println!("值为 : {}", i);
}
// 索引访问
for i in 0..5 {
println!("a[{}] = {}", i, a[i]);
}
// loop无限循环
let s = ['R', 'U', 'N', 'O', 'O', 'B'];
let mut i = 0;
loop {
let ch = s[i];
if ch == 'O' {
break;
}
println!("\'{}\'", ch);
i += 1;
}
// loop获取返回值
let location = loop {
let ch = s[i];
if ch == 'O' {
// 返回值
break i;
}
i += 1;
};
println!(" \'O\' 的索引为 {}", location);
}
五、模式匹配
match 匹配
match 语句必须覆盖所有可能情况,因此 _ 用于匹配未列出的情况。
fn main() {
let day = "Monday";
match day {
"Monday" => println!("新的一周开始了!"),
"Friday" => println!("周五快乐!"),
_ => println!("只是普通的一天"),
}
}
结构体解构匹配
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 5, y: -3 };
match point {
Point { x: 0, y: 0 } => println!("原点"),
Point { x, y } if y > 0 => println!("({},{}) 位于上半平面", x, y),
Point { x, y } => println!("点的坐标: ({},{})", x, y),
}
}
枚举匹配
enum TrafficLight {
Red,
Yellow,
Green,
}
fn traffic_light_action(light: TrafficLight) {
match light {
TrafficLight::Red => println!("请停车!"),
TrafficLight::Yellow => println!("准备起步!"),
TrafficLight::Green => println!("可以通行!"),
}
}
fn main() {
let light = TrafficLight::Green;
traffic_light_action(light);
}
if let 简化模式匹配
fn main() {
let some_value = Some(42);
if let Some(x) = some_value {
println!("匹配到的值: {}", x);
}
}