跳到主要内容

基本命令

安装

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

基本工具

rustc Rust 编译器,负责将你的 Rust 代码翻译成可执行程序。 Cargo:Rust 的官方构建系统和包管理器,简化了项目管理、依赖项处理和各种开发工作流程。

cargo init hello-world cargo build cargo run cargo test cargo fmt

rustUp

examples 是特殊的文件夹,rust可以找到这个

cargo run --example var  //文件夹要带s,命令是不带s

cargo run --examples hello

宏方法

!方法称为宏方法是编译时生产代码的代码 println!("hello world")

设置编译器属性#![allow(unused)]

符号#后跟感叹号!和方括号#![...]表示内部属性。当放在文件开头时,它适用于整个 crate 或模块(在本例中,即整个hello.rs文件)。

allow(unused)该属性本身指示 Rust 编译器抑制通常会针对未使用的变量、函数或导入等内容生成的警告。

vscode的智能提示

@tag:nextEditSuggestions 智能提示开关

println!

println!的用法

    println!("Y is {}", Y); // {}占位符的
println!("NUM is {NUM}"); // 直接内连变量名
println!("{0} + {1} = {2}", Y, x, z ); //位置参数,012表示后面变量的序号

let point = (3,4);
println!("DEBUG tuple: point is {:?}", point); // 更好看一点的打印
println!("DEBUG pretty tuple: point is {:#?}", point);
/*
DEBUG tuple: point is (3, 4)
DEBUG pretty tuple: point is (
3,
4,
)
*/

mut使变量可变

    let mut name = "Minner";
name = "minmin";
println!("name is {name}");

常量可以写在main方法之外

声明:常量使用const关键字而不是句点来声明let。

类型注解:常量的类型必须始终显式注解。

作用域:常量可以在任何作用域中声明,包括全局作用域(任何函数之外)。

命名约定:按照约定,常量名称写成UPPER_SNAKE_CASE(例如,MAX_POINTS)。

值:常量的值必须是常量表达式,这意味着它必须在编译时可确定。它不能是函数调用的结果,也不能是运行时计算的任何其他值。

const NUM: u32 = 123;
fn main(){

println!("NUM is {NUM}");

let mut name = "Minner";
name = "minmin";
println!("name is {name}");

}

const ,let的差别 使用 int 声明的不可变变量let仍然是变量。它们的值在运行时(即执行 int 语句时)设置let并存储在内存中。尽管初始化后不能更改,但它们的行为与运行时值相同。

使用常量const不仅是不可变的;它们的值实际上会被内联到编译后的代码中,无论在哪里使用它们。它们在编译时被解析。你不能将mut与const一起使用。

类型推断 type inference

const Y: i32 = 1;  //:xx这叫类型注解

在某些情况下,尤其是在处理更复杂的类型或泛型编程时,Rust 编译器可能需要类型注解,但您可能希望 Rust 推断具体类型。 用_做推理占位符,这会告诉编译器:“我知道这里需要类型,请自行推断。”

    let age: _ = 30;
println!("age is {age}");

shadowing

Rust 允许你声明一个与先前声明的变量同名的新变量。这种概念被称为“变量遮蔽”。新变量可以是其他的类型

当你对一个变量进行名称遮蔽时,实际上就创建了一个全新的变量。之前的变量仍然存在,但在当前作用域内无法再通过原名访问。 关键在于,类型遮蔽允许你改变变量的类型,而可变变量mut只能改变它的值,但不能改变它的类型。

let age: _ = 30;
println!("age is {age}");
let age: u32 = 50;
println!("age is {age}");
let age: bool = true;
println!("age is {age}");

s函数

函数参数的类型注解是必须要写的

//常规写法
pub fn mul(x: u32, y:u32) -> u32 {
return x * y;
}

// 隐式返回,最后一行不写return,不写分号;
pub fn div(x: u32, y:u32) -> u32 {
x / y
}
// 返回多个值,用()
pub fn add_plus(x: u32, y:u32) -> (u32, bool) {
return (x + y, x + y > 100);
}

// 默认返回空()
pub fn pure_add(x: u32, y: u32){
println!("The sum of {} and {} is {}", x, y, x + y);
}
/*
let res = pure_add(3, 4);
assert_eq!(res, ()); // pure_add returns the unit type `()`
*/

数据类型

Rust 提供了四种主要的标量类型:整数、浮点数、布尔值和字符。

整型 uint int

原生最大只到128。如果一个整数没有显式声明数据类型,默认为i32 u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize


let a8 :i8 = -8;
let a16: i16 = -16;
let a32: i32 = 0;
let a64: i64 = -86;

let b8 : u8 = 8;
let b16: u16 = 16;

usize isize ::MAX ::MIN

在 32 位架构上,isize等价于i32,usize等价于u32。在 64 位架构上,isize是i64,usize是u64。

    let l: u64 = u64::MAX; // 当前类型的最大值
let ll: usize = usize::MAX;
let ll: u64 = ll as u64;
println!("l equals ll: {}", l == ll);
/*
l equals ll: true
*/

类型转换

    let dc: f32 = 3.2;
let dd:i32 = dc as i32; // 浮点转整数,会丢失精度
println!("Cast f32 to i32: {}", dd);
// Cast f32 to i32: 3

let da: i32 = -1;
let db: u32 = da as u32;
println!("Cast i32 to u32: {}", db); // 有符号整数转无符号,符号位会影响数值
// Cast i32 to u32: 4294967295

浮点数

f32:一个单精度浮点数,占用 32 位。 f64:一个双精度浮点数,占用 64 位。

    let c32: f32 = 3.14;
let c64: f64 = 2.71828;
println!("Floating point numbers: {}, {}", c32, c64);

bool

    let d: bool = true;
println!("Boolean: {}", d);

字符

Rust 的 chartype 类型旨在表示单个 Unicode 标量值。

    let  c : char = 'c' ;
let z : char = 'ℤ' ;
let heart : char = '❤' ;
let e : char = '🦀' ; // 表情符号是有效的字符值
println!("Characters: {}, {}, {}, {}", c, z, heart, e);
// Characters: c, ℤ, ❤, 🦀

关于整数溢出 checked_add wrapping_add

--release 表示发布版本,当整数溢出的时候,发布版本与调试运行的时候,行为不一致。发布版本的时候,不会报错。而调试运行的时候,程序会直接停止运行

checked_add

返回一个 Option<T> 整数T类型。

溢出返回None。无溢出则返回Some(result),其中result是计算出的总和。

wrapping_add

显式地使用二进制补码运算执行加法运算。

如果发生溢出,则值会循环,无溢出 直接返回结果值(而不是一个Option)。

fn t_flow(){
let mut x:u8 = u8::MAX;

let over= u8::checked_add(x,1);
println!("u8 max number: {}, u8 overflow: {:?}",u8::MAX, over);
let over = u8::checked_add(1,2);
println!("u8 check overflow: {:?}", over);

let over = u8::wrapping_add(x,1);
println!("u8 max number: {}, u8 allow overflow: {}",u8::MAX, over);
let over = u8::wrapping_add(1,2);
println!("u8 allow overflow: {}", over);
}

/*
u8 max number: 255, u8 overflow: None
u8 check overflow: Some(3)
u8 max number: 255, u8 allow overflow: 0
u8 allow overflow: 3
*/
📢 Share this article