目录
文章目录
Rust的基本语法
Rust的一些操作指令
- rustup update 更新Rust
- rustup self uninstall 卸载Rust
- rustc --version 查看Rust版本号
- rustup doc 打开本地Rust文档
- rustc main.rs 编译Rust源代码文件
- cargo --version 查看Cargo版本号
- cargo new project_name 创建一个Cargo项目
- cargo build 构建Cargo项目(不运行)
- cargo build --release 构建Cargo项目,代码运行更快,但是编译时间更长,用于项目发布版本的构建
- cargo run 构建并运行Cargo项目
- cargo check 检查源代码,确保编译通过,但不产生可执行文件,速度比cargo build快的多
- cargo update 忽略Cargo.lock的锁定,更新Cargo项目
- cargo clippy 类似eslint,lint工具检查代码可以优化的地方
- cargo fmt 类似go fmt,代码格式化
- cargo tree 查看第三方库的版本和依赖关系
- cargo bench 运行benchmark(基准测试,性能测试)
- cargo udeps(第三方) 检查项目中未使用的依赖
你的第一个Rust程序
/*
Rust语言的第一个程序:猜数游戏
*/
// 使用标准库 std 中的 io 模块和 cmp 模块
use std::io;
use std::cmp::Ordering;
// 使用外部库 rand 中的 Rng 模块
use rand::Rng;
fn main() {
let secret_number = rand::thread_rng().gen_range(1..100);
// Rust 使用 Loop 进行无限循环,不使用 While true
loop{
// println! 用来打印语句到终端
println!("请你猜测一个数值:");
// 使用 let 定义一个变量,使用 mut 令其可变
// 使用 String::new() 来创建一个字符串对象
let mut guess = String::new();
// 使用 io 库中的stdin.read_line(&mut guess).expect(msg)
// 进行用户输入,并将其存入变量 guess的存储空间
io::stdin().read_line(&mut guess).expect("无法读取");
// 变量的遮蔽(shadow), 也可以叫作变量的重绑定
let guess: u32 = match guess.trim().parse(){
Ok(num) => num,
Err(_) => continue
};
// 使用模式匹配 match
match guess.cmp(&secret_number){
Ordering::Less => println!("Too samll!"),
Ordering::Greater => println!("Too High!"),
Ordering::Equal => {
println!("You win");
break;
}
}
//在 Rust中,使用 {} 作为占位符进行格式化输出,与 C 语言类似
println!("你猜测的数值是{}", guess);
}
}
数值类型
fn main() {
// 变量与常量
const MAX_POINTS: u32 = 1_024;
let guess: u32 = "42".parse().expect("Error");
// 元组
let tup = (51, 54.2, 55.2, 56.2, 57.2);
let (a, b, c, d, e) = tup;
// 数组
let b_vec = [1, 2, 3, 4, 5, 6];
let a_vec = [3; 5]; // [3,3,3,3,3]
// 语句和表达式
let x = 1; // 这是一个语句
let y = {
let x = x + 1;
x + 3 // 没有加上 ; 分号,他是一个表达式,而不是一个语句
};
// 控制流 if, if 不止能够使用语句,也能使用表达式
let number = 6;
if number < 5 {
println!("{}",number);
}else if number > 10 {
println!("{} 大于10", number);
}else {
println!("The number is higher than 5, but it is lower than 10.");
}
let number = if true {
5} else {
10};
// loop 循环
loop {
println!("{}",number);
break;
}
// 从循环返回值,使用 break
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("result {}", result);
// while 条件循环
let mut number = 8;
while number > 2 {
number = number - 1;
println!("{}", number);
}
// for 循环
// 使用迭代器来生成迭代序列
let vec = [10, 20, 30, 40, 50];
for element in vec.iter(){
println!("the value is {}", element);
}
// 使用 range 来定义循环次数
for element in 0..101 {
println!("the value is {}", element);
}
for element in (0..101).rev() {
println!("the value is {}", element);
}
println!("{}", number);
println!("{}", MAX_POINTS);
println!("{}", guess);
println!("{}, {}, {}, {}, {}", a, b, c, d, e);
println!("{}", a_vec[0]);
println!("{}", b_vec[0]);
println!("{}", y);
}
函数的所有权问题
fn main() {
// 创建一个字符串类型,并进行压栈
let mut s = String::from("Hello");
s.push_str(", world!");
println!("{}", s);
// 当一个变量离开作用域,会自动 drop
// string 类型的复制,复制的是指针
// 在 Rust中,当你把 s1 赋给 s2,s1 就会失效,这叫做所有权的转移
// 这保证了内存中的一段数据,有且只有 1 个拥有者
let s1 = String::from("Hello");
// let s2 = s1;
// 可以使用 Clone方法进行通常意义上的复制,但是比较消耗内存资源
let s2 = s1.clone();
println!("{}", s1);
println!("{}", s2);
//上述的操作是对 Heap的操作,而对 Stack的操作如下
// 你可以对存储在 Stack中的数据进行直接拷贝,而不需要使用clone
let x = 5;
let y = x;
println!("{}, {}",x, y);
println!("\n********************************\n");
// 函数的所有权
let s = String::from("Hello, world");
// 在此处,字符串 s 的所有权转移给函数take_ownership
take_ownership(s);
// 函数执行完毕,将 s 进行 drop,s所有权消失,后续不能再次使用
// 故而再次使用 s 字符串会报错
//println!("{}", s);
let x