init code

This commit is contained in:
nap.liu
2023-12-08 19:41:26 +08:00
commit d1b95f1096
98 changed files with 2890 additions and 0 deletions

7
2.Primitives/2. Primitives/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "Primitives"
version = "0.1.0"

View File

@@ -0,0 +1,8 @@
[package]
name = "Primitives"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,25 @@
fn main() {
// 明确声明变量类型
let logical: bool = true;
let a_float: f64 = 1.0; // 常规类型声明
let an_integer = 5i32; // 后缀类型声明
// 默认的类型推断,整数型默认 i32浮点型默认是 f64
let default_float = 3.0; // `f64`
let default_integer = 7; // `i32`
// 变量类型还可以根据代码的上下文自动推断
let mut inferred_type = 12; // 这里的类型推断为 i64 是因为下面一行代码写的数值范围超过了 i32 类型的有效范围
inferred_type = 4294967296i64; // 这里的数值超过了默认 i32 类型的取值范围,所以进行了类型扩容推断为 i64
// 所有的变量默认都是不可变类型,通过添加 mut 关键字可以让变量的值可修改
let mut mutable = 12; // 可变的 `i32` 类型
mutable = 21;
// 错误!变量可变的前提条件是,变更的值类型不能变,这里报错就是因为尝试把 i32 类型的变量修改为 bool 类型
mutable = true;
// 变量可以通过 let 关键字重新定义遮蔽shadowing来修改变量的类型。
let mutable = true;
}

View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "literals_and_operators"
version = "0.1.0"

View File

@@ -0,0 +1,8 @@
[package]
name = "literals_and_operators"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,44 @@
fn main() {
// 无符号整数加法
println!("1 + 2 = {}", 1u32 + 2);
// 有符号整数减法
println!("1 - 2 = {}", 1i32 - 2);
// TODO ^ 修改 `1i32` 成 `1u32` 会编译失败,因为无符号不能表示负数
// 科学计数法
println!("1e4 is {}, -2.5e-3 is {}", 1e4, -2.5e-3);
// 逻辑表达式语法糖
println!("true AND false is {}", true && false);
println!("true OR false is {}", true || false);
println!("NOT true is {}", !true);
// 二进制操作
// 二进制 位与
// 两个数字二进制的 相同位 都是 1 的时候,结果的对应位置上为 1 否则为 0
println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101);
// 二进制 位或
// 两个数字二进制的 相同位 任意一个 1 的时候,结果的对应位置上为 1 否则为 0
println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101);
// 二进制 位异或
// 两个数字二进制的 相同位 不相同的时候,结果的对应位置上为 1 否则为 0
println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101);
// 二进制 左移
// 数字的二进制位 整体向左移动指定位数 新增的位置补 0
// 0b1 << 5 == 0b100000 == 32
println!("1 << 5 is {}", 1u32 << 5);
// 二进制 右移
// 数字的二进制位 整体向右移动指定位数 移动过程中会丢弃末尾的二进制位
// 0b10000000 >> 2 == 0b100000 == 32 == 0x20
println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2);
// 可以通过在数字中插入 `_` 来让数字读起来更容易一些
// 改特性不会影响数字本身,编译的过程中会自动去掉数字中的 `_`
println!("One million is written as {}", 1_000_000u32);
}

7
2.Primitives/2.2 Tuples/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "tuples"
version = "0.1.0"

View File

@@ -0,0 +1,8 @@
[package]
name = "tuples"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,66 @@
// 元组可以当做函数参数,也可以当做函数返回值使用
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// `let` 关键字可以绑定元组的数据到变量上。
let (int_param, bool_param) = pair;
(bool_param, int_param)
}
// 该结构用于下面代码示例
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
impl std::fmt::Display for Matrix {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "( {} {} )\n( {} {} )", self.0, self.1, self.2, self.3)
}
}
fn transpose(matrix: Matrix) -> Matrix {
Matrix(matrix.0, matrix.2, matrix.1, matrix.3)
}
fn main() {
// 元组可以容纳任意数量的任意类型值
let long_tuple = (
1u8, 2u16, 3u32, 4u64, -1i8, -2i16, -3i32, -4i64, 0.1f32, 0.2f64, 'a', true,
);
// 元组可以通过索引直接访问对应位置上的数据。
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
// 元组可以嵌套使用
let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);
// 元组默认是可打印的
println!("tuple of tuples: {:?}", tuple_of_tuples);
// 但是元组的长度超过12个元素的话就不能打印了。
// let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
// println!("Too long tuple: {:?}", too_long_tuple);
// TODO ^ 移除上面两行代码的注释看看编译错误
let pair = (1, true);
println!("Pair is {:?}", pair);
println!("The reversed pair is {:?}", reverse(pair));
// 因为元组和表达式优先级使用了相同的语法。
// 所以当想创建只有一个元素的元组类型,需要在元素后面加一个逗号来区分是元组还是表达式
println!("One element tuple: {:?}", (5u32,));
// 这个是优先级的表达式,返回一个整数
println!("Just an integer: {:?}", (5u32));
// 元组可以使用 `let` 来进行结构批量赋值给变量。
let tuple = (1, "hello", 4.5, true);
let (a, b, c, d) = tuple;
println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:?}", matrix);
println!("Matrix:\n{}", matrix);
println!("Transpose:\n{}", transpose(matrix));
}

View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "arrays_and_slices"
version = "0.1.0"

View File

@@ -0,0 +1,8 @@
[package]
name = "arrays_and_slices"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,58 @@
use std::mem;
// 该函数借用数组切片slice
fn analyze_slice(slice: &[i32]) {
println!("First element of the slice: {}", slice[0]);
println!("The slice has {} elements", slice.len());
}
fn main() {
// 固定长度和类型的数组,这里可以不声明类型和长度,编译器会自动推断
let xs: [i32; 5] = [1, 2, 3, 4, 5];
// 数组类型是 i32 长度是 500所有 500 个元素初始化为 0.
let ys: [i32; 500] = [0; 500];
// 数组的索引从 0 开始
println!("First element of the array: {}", xs[0]);
println!("Second element of the array: {}", xs[1]);
// `len()` 方法会返回数组的长度。
println!("Number of elements in array: {}", xs.len());
// 因为数组的类型和长度是固定的,编译的时候会直接把数组放在栈上。
println!("Array occupies {} bytes", mem::size_of_val(&xs));
// 数组可以自动创建一个对于该数组的切片slice
println!("Borrow the whole array as a slice.");
analyze_slice(&xs);
// 切片slice可以通过指定一个区间 [起始索引..结束索引] 来借用数组的一部分数据
// `起始索引` 是切片的第一个元素的位置
// `结束索引` 是切片的最后一个元素的位置 + 1 的位置
println!("Borrow a section of the array as a slice.");
analyze_slice(&ys[1..4]);
// 创建一个空的切片 `&[]`:
let empty_array: [u32; 0] = [];
assert_eq!(&empty_array, &[]); // 对空数组创建一个切片引用,实际上这个等于下面的代码。
assert_eq!(&empty_array, &[][..]); // 对空数组创建切片引用,引用范围为整个数组。
// 数组还可以通过 `.get()` 方法安全的访问,该方法会返回一个 `Option`
// 可以通过 `.expect()` 方法来输出一个明确的错误。
for i in 0..xs.len() + 1 {
// Oops, one element too far!
match xs.get(i) {
Some(xval) => println!("{}: {}", i, xval),
None => println!("Slow down! {} is too far!", i),
}
}
// 因为数组类型是明确长度和类型的,所以在编译阶段会进行数组的访问越界检查,
// 一旦发现越界就会报出错误,无法通过编译。
//println!("{}", xs[5]);
// 切片类型在编译阶段是不能知道长度的,
// 所以切片会在运行的过程中检查访问的索引是否越界,一旦越界就会产生 `panic!` 错误。
//println!("{}", xs[..][5]);
}