【Rust】一文掌握 Rust 的详细用法(Rust 备忘清单)
文章目录
- 入门
- 配置 vscode 调试
- Hello_World.rs
- 原始类型
- 格式化
- 打印风格
- 变量
- 注释
- 函数
- 声明宏
- 元变量
- 结构体
- 元组结构体
- 单元结构体
- 语句与表达式
- 语句
- 表达式
- 区间表达式
- Rust 类型
- 类型别名
- 整数
- 浮点数
- 布尔值
- 字符
- 字符串字面量
- 数组
- 切片
- 元组
- Rust 字符串
- 字符串字面量
- 字符串对象
- .capacity()
- with_capacity()
- .contains()
- 添加单个字符
- 添加整个字符串
- 原生字符串
- 字节和字节串
- Rust 动态数组
- 创建动态数组
- 读取元素
- 遍历数组
- 多维数组
- 常用方法
- Rust HashMap\<K,V>
- 使用
- 获取元素
- 遍历
- vec -> HashMap
- Option & Result
- Option
- 使用
- Result
- 使用
- 宏 `?`
- 枚举
- 在结构体中使用枚举
- 枚举的变体
- 模式匹配结构体
- Rust 运算符
- 比较运算符
- 算术运算符
- 位运算符
- 逻辑运算符
- 复合赋值运算符
- Rust 流程控制
- If 表达式
- For 循环
- While 循环
- Loop 循环
- Continue 继续声明
- Break 中断语句
- Rust 模式匹配
- match
- `matches!` 宏
- if let 匹配
- while let
- 其它模式匹配
- for 循环迭代器
- let
- 函数中的模式匹配
- 忽略参数
- 使用 `..` 忽略剩余参数
- 使用 `_` 忽略部分参数
- 匹配命名变量
- `@` 绑定
- 使用匹配守卫
- Rust 函数
- 函数命名
- 参数值
- 返回值
- 永不返回 `!`
- 惯用转换
- &str -> String
- &str -> &[u8]
- &str -> Vec<u8>
- String -> &str
- String -> &[u8]
- String -> Vec<u8>
- &[u8] -> &str
- &[u8] -> String
- &[u8] -> Vec<u8>
- Vec<u8> -> &str
- Vec<u8> -> &[u8]
- Vec<u8> -> String
- 杂项
- 类型断言 type-casting
- 借用
- 解引用
- 作用域
Rust 快速参考备忘单,旨在为编写基本语法和方法提供帮助。
参考:
- Cargo 备忘清单 (jaywcjlove.github.io)
- The Rust Document (doc.rust-lang.org)
- The Rust Reference (doc.rust-lang.org)
- Rust Cheatsheet (phaiax.github.io)
- Rust 标准库文档中文版 (jaywcjlove.github.io)
- Rust 程序设计语言 中文版 (jaywcjlove.github.io)
- Rust By Example 中文版 (jaywcjlove.github.io)
- Rust 参考手册中文版 (jaywcjlove.github.io)
- RustDoc 手册中文版 (jaywcjlove.github.io)
- Rust Cookbook 中文版 (jaywcjlove.github.io)
入门
配置 vscode 调试
配置参考。下载 CodeLLDB,选择 rust 自动生成 launch.json 文件
{"configurations": [// 添加一下行,使 vec/hashmap 等类型显示正常"sourceLanguages": ["rust"]]
}
将编译文件与标准库的位置进行映射
{"lldb.launch.sourceMap": {// 你自己的映射 hash 和映射路径"/rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f": "/Users/feiwu/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust"}
}
Hello_World.rs
fn main() {println!("Hello, World!");
}
编译运行
$ rustc Hello_World.rs
$ ./Hello_WorldHello, World!
原始类型
| :- | :- |
|---|---|
bool | 布尔值 (true / false) |
char | 字符 |
f32, f64 | 32 位、64 位浮点数 |
i64, i32, i16, i8 | 有符号 16- … 整数 |
u64, u32, u16, u8 | 无符号 16 位,… 整数 |
isize | 指针大小的有符号整数 |
usize | 指针大小的无符号整数 |
查看: Rust 类型
格式化
// 单个占位符
println!("{}", 1);
// 多个占位符
println!("{} {}", 1, 3);
// 位置参数
println!("{0} 是 {1} {2},{0} 也是 {3} 编程语言", "Rust", "cool", "language", "safe");
// 命名参数
println!("{country} 是一个团结的国家", country = "China");
// 占位符特征 :b 表示二进制, :0x 表示十六进制, :o 表示八进制
println!("让我们打印 76 是二进制的 {:b} ,十六进制等价物是 {:0x} 八进制等价物是 {:o}", 76, 76, 76);
// 调试特征
println!("使用调试特征 {:?} 在此处打印我们想要的任何内容", (76, 'A', 90));// 1.58 中的新格式字符串
let x = "world";
println!("Hello {x}!");
打印风格
// 打印输出
print!("Hello World\n");
// 打印后追加新行
println!("追加新行");
// 打印为错误
eprint!("这是一个错误\n");
// 打印为新行错误
eprintln!("这是新行的错误");
变量
// 初始化和声明变量
let some_variable = "This_is_a_variable";
// 使变量可变
let mut mutable_variable = "Mutable";
// 分配多个变量
let (name, age) = ("ElementalX", 20);
// (全局)常量
const SCREAMING_SNAKE_CASE:i64 = 9;
注释
// 行注释
/*.............块注释 */
/// 外部文档注释
//! 内部文档评论
另见: 注释 (doc.rust-lang.org)
函数
fn test(){println!("这是一个函数!");
}
fn main(){test();
}
查看: Functions
声明宏
macro_rules! foo {($l:tt) => { bar!($l); }
}
macro_rules! bar {(3) => {}
}
foo!(3);
元变量
| :- | :- |
|---|---|
item | 程序项 |
block | 块表达式 |
stmt | 语句 (注意此选择器不匹配句尾的分号) |
pat | 模式 |
expr | 表达式 |
ty | 类型 |
ident | 标识符或关键字 |
path | 类型表达式 形式的路径 |
tt | token 树(单个 token 或宏匹配定界符 ()、[] 或 {} 中的标记) |
meta | 属性,属性中的内容 |
lifetime | 生存期 token |
vis | 可能为空的可见性限定符 |
literal | 匹配 -? 字面量表达式 |
结构体
结构体是一个使用关键字 struct 定义的标称型(nominal)结构体类型
struct Point { x: i32, y: i32 }
let p = Point { x: 10, y: 11 };
let px: i32 = p.x;
元组结构体
struct Color (i32, i32, i32);
let black = Color(0,0,0);
单元结构体
不关心该类型的内容, 只关心它的行为。
struct Solution;
impl Solution{// ...
}
语句与表达式
在 rust 中,语句无需返回值,而表达式总要返回值
语句
let a = "hello".to_string();
let b = a + " world";
println!("{}", b);
表达式
fn main(){let x = {let a = "hello".to_string();a + " world"};println!("{}", x);// hello world
}
区间表达式
| 产生式/句法规则 | 句法 | 类型 | 区间语义 |
|---|---|---|---|
| RangeExpr | start..end | std::ops::Range | start ≤ x < end |
| RangeFromExpr | start.. | std::ops::RangeFrom | start ≤ x |
| RangeToExpr | ..end | std::ops::RangeTo | x < end |
| RangeFullExpr | .. | std::ops::RangeFull | - |
| RangeInclusiveExpr | start..=end | std::ops::RangeInclusive | start ≤ x ≤ end |
| RangeToInclusiveExpr | ..=end | std::ops::RangeToInclusive | x ≤ end |
Rust 类型
类型别名
type Point = (u8, u8);
let p: Point = (41, 68);
整数
let mut a: u32 = 8;
let b = 877_u64;
let c = 8999i64;
let d = -90;
浮点数
let mut sixty_bit_float: f64 = 89.90;
let thirty_two_bit_float: f32 = 7.90;
let just_a_float = 69.69;
布尔值
let true_val: bool = true;
let false_val: bool = false;
let just_a_bool = true;
let is_true = 8 < 5; // => false
字符
let first_letter_of_alphabet = 'a';
let explicit_char: char = 'F';
let implicit_char = '8';
let emoji = "\u{1f600}"; // => 😀
字符串字面量
let community_name = "AXIAL";
let no_of_members: &str = "ten";
println!("社区的名称是 {community_name},它有 {no_of_members} 个成员");
查看: 字符串
数组
这里介绍的是固定长度的数组。rust 中常用的是集合类型 vec 表示的动态数组
┌─────┬─────┬─────┬─────┬─────┬─────┐
| 92 | 97 | 98 | 99 | 98 | 94 |
└─────┴─────┴─────┴─────┴─────┴─────┘0 1 2 3 4 5
let array: [i64; 6] = [92,97,98,99,98,94];
let mut array: [i32 ; 3] = [2,6,10];
array[1] = 4;
array[2] = 6;
使用 mut 关键字使其可变
切片
let mut array: [ i64; 4] = [1,2,3,4];
// 下限包括在内,上限不包括在内
let mut slices: &[i64] = &array[0..3]
println!("切片的元素是:{slices:?}");
元组
let tuple = (1, 'A' , "Cool", 78, true);
Rust 字符串
字符串字面量
let cs:&str = "备忘清单";
// => 为开发者分享备忘单
println!("为开发者分享 {cs}");
字符串对象
// 创建一个空字符串对象
let my_string = String::new;
// 转换为字符串对象
let S_string = a_string.to_string()
// 创建一个初始化的字符串对象
let lang = String::from("Rust");
println!("First language is {lang}");
.capacity()
let rand = String::from("Random String");
rand.capacity() // => 13
以字节为单位计算字符串的容量
with_capacity()
let s = String::with_capacity(10);
指定一个足够大的容量值,来减少内存拷贝
.contains()
let name = String::from("ElementalX");
name.contains("Element") // => true
检查子字符串是否包含在原始字符串中
添加单个字符
let mut half_text = String::from("Hal");
half_text.push('f'); // => Half
添加整个字符串
let mut hi = String::from("Hey there...");
hi.push_str("How are you doing??");
// => Hey there...How are you doing??
println!("{hi}");
原生字符串
let str1 = r#"\hello"#;
println!("{}", str1);
// \hello
原生字符串,无需增加转义字符(\)转义
字节和字节串
let str2 = b'a';
println!("{}", str2);
// 97
let str3 = b"\\hello";
println!("{:?}", str3);
// [92, 104, 101, 108, 108, 111]
let str4 = br#"\hello"#;
println!("{:?}", str4);
// [92, 104, 101, 108, 108, 111]
Rust 动态数组
创建动态数组
let v: Vec<i32> = Vec::new();
// 使用宏
let v1 = vec![1, 2, 3];
读取元素
let v = vec![1, 2, 3, 4, 5];let element = &v[100];
// panic,越界
let element2 = v.get(100);
println!("{:?}", element2);
//None
遍历数组
-
只读取数组中的元素
let v = vec![1, 2, 3]; for i in &v {println!("{}", i); } -
遍历的同时修改数组中的元素
let mut v = vec![1, 2, 3]; for i in &mut v {*i += 10 }
多维数组
j0 j1 j2 j3 j4 j5┌────┬────┬────┬────┬────┬────┐
i0 | 1 | 2 | 3 | 4 | 5 | 6 |├────┼────┼────┼────┼────┼────┤
i1 | 6 | 5 | 4 | 3 | 2 | 1 |└────┴────┴────┴────┴────┴────┘
let arr = vec![vec![1, 2, 3, 4, 5, 6],vec![6, 5, 4, 3, 2, 1]
];
常用方法
| - | :- |
|---|---|
len() | 返回 vec 的长度 |
is_empty() | vec 是否为空 |
push(value) | 在 vec 尾部插入元素 |
pop() | 删除并返回 vec 尾部的元素或者返回 None |
insert(index,element) | 在指定索引处插入元素 |
remove(index) | 删除指定索引处的元素并返回被删除的元素,索引越界将 panic 报错退出 |
clear() | 清空 vec |
append(vec) | 将另一个 vec 中的所有元素追加移入 vec 中,移动的 vec 变为空 |
truncate(len) | 将 vec 截断到指定长度,多余的元素被删除 |
retain(f) | 根据给定的函数,保留满足条件的元素 |
drain(range) | 删除 vec 中指定范围的元素,同时返回一个迭代该范围所有元素的迭代器 |
split_off(index) | 切分 vec,索引左边的元素保留在原 vec 中(含索引),索引右边的元素(不含索引)在返回的 vec 中 |
Rust HashMap<K,V>
使用
use std::collections::HashMap;fn main() {let mut map: HashMap<String, i32> = HashMap::new();map.insert(String::from("blue"), 100);// 查询Yellow对应的值,若不存在则插入默认值let v: &mut i32 =map.entry("Yellow".to_string()).or_insert(5);let v: &mut i32 = map.entry("Yellow".to_string()).or_insert(50); // 不会修改值
}
获取元素
let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);let team_name = String::from("Blue");
let score: Option<&i32> = scores.get(&team_name);
遍历
let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);for (key, value) in &scores {println!("{}: {}", key, value);
}
vec -> HashMap
let teams_list = vec![("中国队".to_string(), 100),("美国队".to_string(), 10),("日本队".to_string(), 50),
];
let teams_map: HashMap<_,_> =teams_list.into_iter().collect();
let teams = vec![String::from("blue"),String::from("red")];
let intial_scores = vec![10,50];
let scores:HashMap<_,_> =teams.iter().zip(intial_scores.iter()).collect();
Option & Result
Option
enum Option<T> {Some(T),None,
}
使用
fn main(){let a = Some(5);// 直接获取原始值println!("{}", a.unwrap());// 给出错误信息let x: Option<&str> = None;x.expect("fruits are healthy"); // panics 带有 `fruits are healthy`
}
Result
enum Result<T, E> {Ok(T),Err(E),
}
使用
use std::fs::File;fn main() {let f: Result<File,Error> = File::open("hello.txt");let f = match f {Ok(file) => file,Err(error) => {panic!("Problem opening the file: {:?}", error)},};
}
宏 ?
? 只能用于返回结果是 Result 或者 Option 的函数,或者实现了 Try 类型
use std::fs::File;
use std::io::{self, Read};fn read_username_from_file() -> Result<String, io::Error> {let mut s = String::new();File::open("hello.txt")?.read_to_string(&mut s)?;Ok(s)
}
fn first(arr: &[i32]) -> Option<&i32> {let v = arr.get(0)?;Some(v)
}
枚举
在结构体中使用枚举
enum IpAddrKind {V4,V6,
}
struct IpAddr {kind: IpAddrKind,address: String,
}fn main(){let ip = IpAddr{kind: IpAddrKind::V4,address: String::from("127.0.0.1")};
}
枚举的变体
enum IpAddrKind {V4(u8, u8, u8, u8),V6(String),
}fn main() {let home = IpAddrKind::V4(127, 0, 0, 1);let loopback = IpAddrKind::V6(String::from("::1"));
}
enum Message{Quit,Move {x:i32, y:i32},Write(String),ChangeColor(i32, i32, i32),
}
fn main(){let q = Message::Quit;let m = Message::Move {x:10, y:20};let w = Message:: Write(String::from("hello"));let c = Message::ChangeColor(10, 20, 30);
}
模式匹配结构体
#[derive(Debug)]
enum Grade {A,B,C,
}
enum Subject {Math(Grade),English(Grade),
}fn subject_grade(sub: Subject) {match sub {Subject::Math(grade) => println!("The Math is {:?}", grade),Subject::English(grade) => println!("The Math is {:?}", grade),}
}fn main() {subject_grade(Subject::Math(Grade::A));
}
Rust 运算符
比较运算符
| :- | :- |
|---|---|
e == f | e 等于 f |
e != f | e 不等于 f |
e < f | e 小于 f |
e > f | e 大于 f |
e <= f | e 小于或等于 f |
e >= f | e 大于或等于 f |
let (e, f) = (1, 100);
let greater = f > e; // => true
let less = f < e; // => false
let greater_equal = f >= e; // => true
let less_equal = e <= f; // => true
let equal_to = e == f; // => false
let not_equal_to = e != f; // => true
算术运算符
| :- | :- |
|---|---|
a + b | a 被添加到 b |
a - b | 从 a 中减去b |
a / b | a 除以 b |
a % b | 通过与 b 相除得到 a 的余数 |
a * b | a 与 b 相乘 |
let (a, b) = (4, 5);
let sum: i32 = a + b; // => 9
let subtractions: i32 = a - b; // => -1
let multiplication: i32 = a * b; // => 20
let division: i32 = a / b; // => 0
let modulus: i32 = a % b; // => 4
位运算符
| 运算符 | 描述 |
|---|---|
g & h | 二进制与 |
g | h | 二进制或 |
g ^ h | 二进制异或 |
g ~ h | 二进制补码 |
g << h | 二进制左移 |
g >> h | 二进制右移 |
let (g, h) = (0x1, 0x2);
let bitwise_and = g & h; // => 0
let bitwise_or = g | h; // => 3
let bitwise_xor = g ^ h; // => 3
let right_shift = g >> 2; // => 0
let left_shift = h << 4; // => 32
逻辑运算符
| 示例 | 意义 |
|---|---|
c && d | 两者都是真的_(AND)_ |
c || d | 要么是真的_(OR)_ |
!c | c 为假 (NOT) |
let (c, d) = (true, false);
let and = c && d; // => false
let or = c || d; // => true
let not = !c; // => false
复合赋值运算符
let mut k = 9;
let mut l = k;
| 运算符 | 描述 |
|---|---|
k += l | 添加一个值并赋值,然后 k=9 |
k -= l | Substrate 一个值并赋值,然后 k=18 |
k /= l | 除以一个值并赋值,然后 k=9 |
k *= l | 乘一个值并赋值,然后 k=81 |
k |= l | 按位或并赋值,则 k=89 |
Rust 流程控制
If 表达式
let foo = 12;
let bar = 13;
if foo == bar {println!("foo 等于 bar");
} else if foo < bar {println!("foo 小于 bar");
} else if foo != bar {println!("foo 不等于 bar");
} else {println!("Nothing");
}
For 循环
let mut vec = [1, 2, 3];
for v in &mut vec {*v -= 1;println!("v 的值为:{v}");
}
| 使用方法 | 等价使用方式 | 所有权 |
|---|---|---|
| for item in collection | for item in collection.into_iter() | 转移所有权 |
| for item in &collection | for item in collection.iter() | 不可变借用 |
| for item in &mut collection | for item in collection.iter_mut() | 可变借用 |
While 循环
let mut check = 0;
while check < 11{println!("check 是:{check}");check += 1;println!("递增后:{check}");if check == 10{break; // 停止 while}
}
Loop 循环
loop {println!("你好,世界永远!");
}
无限循环表示
Continue 继续声明
for (v, c) in (0..10+1).enumerate(){println!("{c} 数字循环");if v == 9{println!("我们继续?");continue;}println!{"v 的值为:{v}"};
}
Break 中断语句
break 可以单独使用,也可以带一个返回值
let mut i = 1;
let res = loop {println!("i 是 {i}");if i > 100 {break i - 100;}i *= 2;
}println!("{res}"); // 28
Rust 模式匹配
match
match 模式匹配,使用 a | b 表示匹配 a 或 b,使用 _,表示匹配剩余所有选项
fn main(){let grade = Grade::A;match grade {Grade::A => println!("Good"),Grade::B => println!("Not bad"),Grade::C | Grade::D => println!("Come on"),_ => println!("emmm"),}
}enum Grade {A,B,C,D,E,F,
}
matches! 宏
它可以将一个表达式跟模式进行匹配,然后返回匹配的结果 true 或 false
assert!(matches!('x' ',A'..='Z' | 'a'..='z'));
assert!(matches!(Some(101), Some(x) if x > 100));
if let 匹配
match 表达式需要匹配所有的枚举才能结束,但通常我们只需要匹配我们需要的值
let x = 3;
match Some(x) {Some(3) => println!("I guess that x is 3"),_ => ()
}
使用 if let
let x = 3;
if let Some(3) = Some(x) {println!("I guess that x is 3");
}
while let
let mut stack = vec![];stack.push(1);
stack.push(2);
stack.push(3);while let Some(top) = stack.pop() {println!("{}", top);
}
其它模式匹配
for 循环迭代器
for (i, v) in collection.iter().enumerate(){}
let
let (x, _, y) = (1, 2, 3);
println!("{x},{y}");
fn get_count_item(s: &str) -> (&str, &str) {let mut it = s.split(' ');let (Some(str1),Some(str2)) = (it.next(),it.next()) else {panic!("Can't segment count item pair");};(str1, str2)
}
函数中的模式匹配
fn add((x, y): (i32, i32)) -> i32 {x + y
}fn main(){let sum = add(1, 2);println!("{sum}");
}
忽略参数
使用 .. 忽略剩余参数
struct Point {x: i32,y: i32,z: i32,
}let origin = Point { x: 0, y: 0, z: 0 };match origin {Point { x, .. } => println!("x is {}", x),
}
使用 _ 忽略部分参数
let hello = ('h', 'e', 'l', 'l', 'o');match hello {(h, _, _, l, o) => {println!("char: {}, {}, {}", h, l, o)},
}
匹配命名变量
以下代码,只要给定的 x 是 Some 类型,但 Some 中的值不是 1,都会匹配到 y
let x = Some(10);
match x {Some(1) => println!("x = 1"),Some(y) => println!("y = {:?}", y),_ => println!("None"),
}// y = 10
@ 绑定
@ 运算符允许为一个字段绑定另外一个变量。
let grade = 'A';
match grade {good @ 'A'..='C' => println!("your grade is {}", good),_ => println!("Come on"),
}
#[derive(Debug)]
struct Point {x: i32,y: i32,
}
fn main(){let p @ Point {x: px, y: py } = Point {x: 10, y: 23};println!("x: {}, y: {}", px, py);println!("{:?}", p);
}
如果使用 |,需要使用 (),进行多个模式的绑定
match 1 {num @ (1 | 2) => {println!("{}", num);}_ => {}
}
使用匹配守卫
let x = Some(2);
match x {Some(1) => println!("x = 1"),Some(y) if y == 2 => println!("y = {:?}", y),_ => println!("No match"),
}// y = 2
Rust 函数
函数命名
rust 的函数使用蛇形命名法(snake case)
fn print_message(){println!("Hello, Quick Reference!");
}
参数值
rust 需要为函数的参数标明确定的类型
fn another_fn(a:u8, b: &str){println!("我是 u8:{}", a);println!("我是 &str:{}", b);
}fn main(){another_fn(10, "hello")
}
返回值
如果不指定返回值,rust 默认返回 () 类型
// 在 bin 中的入口函数默认返回 ()
fn main(){}
使用 -> 指定返回值,如果表达式在最后一行,无需使用 return
fn add(a:i32, b:i32) -> i32 {if a + b < 100 {return a - b;}a + b
}
永不返回 !
fn dead_end() -> ! {panic!("panic!!!!!");
}
惯用转换
&str -> String
String::from("str");
"str".to_string();
"str".to_owned();
&str -> &[u8]
"str".as_bytes();
或者你也可以使用 b""
println!("{:?}", b"str");
&str -> Vec
"str".as_bytes().to_vec();
"str".as_bytes().to_owned();
String -> &str
let s = String::from("str");
let r = s.as_str();
String -> &[u8]
let s = String::from("str");
let v = s.as_bytes();
String -> Vec
let s = String::from("str");
let v = s.into_bytes();
&[u8] -> &str
let b = "str".as_bytes();
let str = std::str::from_utf8(b).unwrap();
&[u8] -> String
let b = "str".as_bytes();
let str = String::from_utf8(b.to_vec()).unwrap();
&[u8] -> Vec
let b = "str".as_bytes();
let str = b.to_vec();
let b = "str".as_bytes();
let str = b.to_owned();
Vec -> &str
let b = "str".as_bytes().to_vec();
let s = std::str::from_utf8(&b).unwrap();
Vec -> &[u8]
let b = "str".as_bytes().to_vec();
let s = b.as_slice();
Vec -> String
let b = "str".as_bytes().to_vec();
let s = String::from_utf8(b).unwrap();
杂项
类型断言 type-casting
let a_int = 90; // int
// int 到 float
let mut type_cast = (a_int as f64);
let orginal: char = 'I';
// char 到 int => 73
let type_casted: i64 = orginal as i64;
要在 Rust 中执行类型转换,必须使用 as 关键字
借用
let mut foo = 4;
let mut borrowed_foo = &foo;
println!("{borrowed_foo}");
let mut bar = 3;
let mut mutable_borrowed_bar = &mut bar;
println!("{mutable_borrowed_bar}");
这里借用的值使用 & 运算符从值一中借用值
解引用
let mut borrow = 10;
let deref = &mut borrow;
println!("{}", *deref);
* 操作符用于解引用
作用域
{// 范围仅限于此大括号let a_number = 1;
}
println!("{a_number}");
这将产生错误,因为变量 a_number 的生命周期在大括号处结束
相关文章:
【Rust】一文掌握 Rust 的详细用法(Rust 备忘清单)
文章目录 入门配置 vscode 调试Hello_World.rs原始类型格式化打印风格变量注释函数声明宏元变量结构体元组结构体单元结构体 语句与表达式语句表达式 区间表达式 Rust 类型类型别名整数浮点数布尔值字符字符串字面量数组切片元组 Rust 字符串字符串字面量字符串对象.capacity()…...
为什么后端接口返回数字类型1.00前端会取到1?
这得从axios中得默认值说起: Axios 的 transformResponse axios 在接收到服务器的响应后,会通过一系列的转换函数(transformResponse)来处理响应数据,使其适合在应用程序中使用。默认情况下,axios 的 tran…...
单片机串口打印调试信息②
在STM32开发中,使用串口(UART)打印调试信息是调试嵌入式程序的核心手段。以下是基于STM32 HAL库的详细实现步骤和调试策略: 一、硬件准备 硬件连接: STM32开发板:以STM32F4系列为例,选择任意UAR…...
Windows下安装常用软件--MySQL篇
Windows下安装常用软件--MySQL篇 文章说明安装指导安装MySQL脚本 资料下载 文章说明 记录一下Windows下安装zip版的MySQL,采用简洁的方式安装,便于学习使用;作为对该篇文章的修正与完善(MySQL 关于 zip安装) 安装指导 …...
Qt 高效读写JSON文件,玩转QJsonDocument与QJsonObject
一、前言 JSON作为轻量级的数据交换格式,已成为开发者必备技能。Qt框架为JSON处理提供了完整的解决方案,通过QJsonDocument、QJsonObject和QJsonArray三大核心类,轻松实现数据的序列化与反序列化。 JSON vs INI 特性JSONINI数据结构支持嵌…...
计算机网络——数据链路层的功能
目录 物理链路 逻辑链路 封装成帧(组帧) 帧定界 透明传输 SDU 差错控制 可靠传输 流量控制 介质访问控制 主机需要实现第一层到第五层的功能,而路由器这种节点只需要实现第一层到第三层的这些功能 假设左边用户需要给右边用户发送…...
第60天:Web攻防-XSS跨站文件类型功能逻辑SVGPDFSWFPMessageLocalStorage
#知识点 1、Web攻防-XSS跨站-文件类型-html&pdf&swf&svg 2、Web攻防-XSS跨站-功能逻辑-postMessage&localStorage 术语:上传xss->其实就是将有恶意js代码的各类文件(swf,pdf,svg,html.xml等)上传->访问该文件->让浏…...
C/C++都有哪些开源的Web框架?
CppCMS CppCMS是一个采用C语言开发的高性能Web框架,通过模版元编程方式实现了在编译期检查RESTful路由系统,支持传统的MVC模式和多种语言混合开发模式。 CppCMS最厉害的功能是WebSocket,10万连接在内存中长期保存占用的大小不超过600MB&…...
RISC-V AIA学习2---IMSIC
我在学习文档这章时,对技术术语不太理解,所以用比较恰当的比喻来让自己更好的理解。 比较通俗的理解: 将 RISC-V 系统比作一个工厂: hart → 工厂的一条独立生产线IMSIC → 每条生产线配备的「订单接收员」MSI 中断 → 客户通过…...
2024年MathorCup数学建模B题甲骨文智能识别中原始拓片单字自动分割与识别研究解题全过程文档加程序
2024年第十四届MathorCup高校数学建模挑战赛 B题 甲骨文智能识别中原始拓片单字自动分割与识别研究 原题再现: 甲骨文是我国目前已知的最早成熟的文字系统,它是一种刻在龟甲或兽骨上的古老文字。甲骨文具有极其重要的研究价值,不仅对中国文…...
Python----计算机视觉处理(Opencv:霍夫变换)
一、霍夫变换 霍夫变换是图像处理中的一种技术,主要用于检测图像中的直线、圆或其他形状。其基本思想就是将图像空间中的点映射到参数空间中,通过在参数空间中寻找累计最大值来实现对特定形状的检测。 二、 霍夫直线变换 那么对于一个二值化后的图形来说…...
多语言生成语言模型的少样本学习
摘要 大规模生成语言模型,如GPT-3,是极具竞争力的少样本学习模型。尽管这些模型能够共同表示多种语言,但其训练数据以英语为主,这可能限制了它们的跨语言泛化能力。在本研究中,我们在一个涵盖多种语言的语料库上训练了…...
k8s存储介绍(二)Secret
Kubernetes(K8s)提供了一种安全的方式来存储和管理敏感信息,如密码、OAuth 令牌和 SSH 密钥,这就是 Secret。使用 Secret 可以避免将敏感数据硬编码到 Pod 规范或容器镜像中,从而提高安全性和可管理性。 1. Secret 的…...
代理IP与AI的碰撞:网络安全新防线解码
目录 一、代理IP:网络世界的“隐形斗篷” 二、AI加持:代理IP的“智能升级包” 三、协同作战:五大核心应用场景 场景1:智能风控系统 场景2:跨境电商竞品分析 场景3:智能汽车安全测试 场景4:…...
QT开发(4)--各种方式实现HelloWorld
目录 1. 编辑框实现 2. 按钮实现 前面已经写过通过标签实现的了,所以这里就不写了,通过这两个例子,其他的也是同理 1. 编辑框实现 编辑框分为单行编辑框(QLineEdit)双行编辑框(QTextEdit)&am…...
UniApp 生命周期钩子的应用场景
UniApp 生命周期钩子的应用场景 应用生命周期钩子的应用场景 onLaunch 应用初始化:在应用第一次启动时进行全局数据的初始化,比如设置全局配置信息、初始化用户登录状态等。例如,在应用启动时检查本地存储中是否有用户的登录信息࿰…...
macOS 安装 Miniconda
macOS 安装 Miniconda 1. Quickstart install instructions2. 执行3. shell 上初始化 conda4. 关闭 终端登录用户名前的 base参考 1. Quickstart install instructions mkdir -p ~/miniconda3 curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o…...
可发1区的超级创新思路(python\matlab实现):基于周期注意力机制的TCN-Informer时间序列预测模型
首先声明,该模型为原创!原创!原创!且该思路还未有成果发表,感兴趣的小伙伴可以借鉴! 一、应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、电机故障检测等等 二、模型整体介绍(本文以光伏功率预测为例) 1.1 核心创新点 本模型通过三阶段…...
Nordic Semiconductor 芯片(如 nRF52/nRF53 系列)的 VSCode 开发环境的步骤
目录 概述 1. 安装必要工具链 2. 安装 VSCode 扩展 3. 配置环境变量 4. 克隆/配置 Nordic SDK 5. 创建 VSCode 项目 6. 配置调试 7. 构建与烧录 8. 其他工具 总结 概述 本文主要介绍Nordic Semiconductor 芯片(如 nRF52/nRF53 系列)的 VSCode…...
Flutter 输入组件 Radio 详解
1. 引言 在 Flutter 中,Radio 是用于单选的按钮组件,适用于需要用户在多个选项中选择一个的场景,如表单、设置选项等。Radio 通过 value 和 groupValue 进行状态管理,并结合 onChanged 监听选中状态的变化。本文将介绍 Radio 的基…...
3.23学习总结
完成了组合Ⅲ,和电话号码的字母组合两道算法题,都是和回溯有关的,很类似。 学习了static的关键字和继承有关知识...
Spring Boot整合Activiti工作流详解
1. 概述 Spring Boot与Activiti的整合可以大大简化工作流应用的开发。Spring Boot提供了自动配置和依赖管理,而Activiti则提供了强大的工作流功能。通过整合,我们可以快速构建基于工作流的业务系统。 本文将详细介绍Spring Boot与Activiti的整合方法,并通过一个请假流程的…...
C# System.Text.Encoding 使用详解
总目录 前言 在C#编程中,处理字符串和字节数组之间的转换是一个常见的任务。System.Text.Encoding类及其派生类提供了丰富的功能,帮助开发者实现不同字符编码之间的转换。本文将详细讲解System.Text.Encoding类的使用方法,包括常用编码的介绍…...
力扣刷题-热题100题-第23题(c++、python)
206. 反转链表 - 力扣(LeetCode)https://leetcode.cn/problems/reverse-linked-list/solutions/551596/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/?envTypestudy-plan-v2&envIdtop-100-liked 常规法 记录前一个指针,当前指针&am…...
机器学习-基于KNN算法手动实现kd树
目录 一、概括 二、KD树的构建流程 1.循环选轴 2.选择分裂点 三、kd树的查询 1.输入我们要搜索的点 2.递归向下遍历: 3.记录最近点 4.回溯父节点: 四、KD树的优化与变种: 五、KD树代码: 上一章我们将了机器学习-手搓KN…...
Unity Shader 的编程流程和结构
Unity Shader 的编程流程和结构 Unity Shader 的编程主要由以下三个核心部分组成:Properties(属性)、SubShader(子着色器) 和 Fallback(回退)。下面是它们的具体作用和结构: 1. Pr…...
vue3 项目的最新eslint9 + prettier 配置
注意:eslint目前升级到9版本了 在 ESLint v9 中,配置文件已经从 .eslintrc 迁移到了 eslint.config.js 配置的方式和之前的方式不太一样了!!!! 详见自己的语雀文档:5、新版eslint9prettier 配…...
SAP GUI Script for C# SAP脚本开发快速指南与默认主题问题
SAP GUI Script for C# 快速指南 SAP 脚本的快速使用与设置. 解决使用SAP脚本执行后,默认打开的SAP是经典主题的问题 1. 解决默认主题问题 如果您使用的是SAP GUI 740,并遇到无法打开对话框的问题,请先将主题设置为经典主题(Classic Theme…...
JAVA泛型的作用
1. 类型安全(Type Safety) 在泛型出现之前,集合类(如 ArrayList、HashMap)只能存储 Object 类型元素,导致以下问题: 问题:从集合中取出元素时,需手动强制类型转…...
Git Flow 分支管理策略
优势 清晰的分支结构:每个分支都有明确的用途,便于团队协作。 稳定的 master 分支:生产环境代码始终稳定。 灵活的发布管理:通过发布分支和热修复分支,可以灵活管理版本发布和紧急修复。 主要分支 master 分支 代表…...
