diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rust/.vscode/tasks.json b/rust/.vscode/tasks.json new file mode 100644 index 0000000..4df0b04 --- /dev/null +++ b/rust/.vscode/tasks.json @@ -0,0 +1,49 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cargo", + "command": "run", + "args": [ + "--package", + "variables", + "--bin", + "variables" + ], + "env": { + "RUST_BACKTRACE": "short", + "HOSTNAME": "044004e12e1c", + "HOME": "/home/vscode", + "RUSTUP_HOME": "/usr/local/rustup", + "PATH": "/vscode/vscode-server/bin/linux-x64/863d2581ecda6849923a2118d93a088b0745d9d6/bin/remote-cli:/usr/local/cargo/bin:/usr/local/cargo/bin:/usr/local/cargo/bin:/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/vscode/.local/bin", + "VSCODE_AGENT_FOLDER": "/home/vscode/.vscode-server", + "SHELL": "/bin/bash", + "RUST_VERSION": "1.75.0", + "PWD": "/vscode/vscode-server/bin/linux-x64/863d2581ecda6849923a2118d93a088b0745d9d6", + "CARGO_HOME": "/usr/local/cargo", + "VSCODE_HANDLES_SIGPIPE": "true", + "VSCODE_AMD_ENTRYPOINT": "vs/workbench/api/node/extensionHostProcess", + "VSCODE_HANDLES_UNCAUGHT_ERRORS": "true", + "VSCODE_NLS_CONFIG": "{\"locale\":\"en\",\"osLocale\":\"en\",\"availableLanguages\":{}}", + "REMOTE_CONTAINERS_IPC": "/tmp/vscode-remote-containers-ipc-01c75401-8980-4bd2-a51b-1e351d0e5863.sock", + "LS_COLORS": "", + "REMOTE_CONTAINERS_SOCKETS": "[]", + "USER": "vscode", + "SHLVL": "1", + "PROMPT_DIRTRIM": "4", + "_": "/bin/cat", + "REMOTE_CONTAINERS": "true", + "BROWSER": "/vscode/vscode-server/bin/linux-x64/863d2581ecda6849923a2118d93a088b0745d9d6/bin/helpers/browser.sh", + "VSCODE_CWD": "/vscode/vscode-server/bin/linux-x64/863d2581ecda6849923a2118d93a088b0745d9d6", + "ELECTRON_RUN_AS_NODE": "1", + "VSCODE_IPC_HOOK_CLI": "/tmp/vscode-ipc-fa17bf85-743b-43c0-bc2d-6c93e6786825.sock", + "VSCODE_L10N_BUNDLE_LOCATION": "" + }, + "problemMatcher": [ + "$rustc" + ], + "group": "build", + "label": "rust: run variables" + } + ] +} diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..a6daf1d --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "variables" +version = "0.1.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..f1cad76 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/README.md b/rust/README.md new file mode 100644 index 0000000..0f70992 --- /dev/null +++ b/rust/README.md @@ -0,0 +1,56 @@ +# 学习 rust + +## 开始:使用 vscode + docker 学习 rust + +安装 vscode 插件: + +- remote.remote-containers +- remote.vscode-remote-extensionpack + +```sh +git clone https://github.com/microsoft/vscode-remote-try-rust.git +``` + +1. vscode 中关闭 http.proxy 代理配置。 +2. Windows 中启动系统全局代理。 +3. 打开 docker。 +4. vscode 中运行 `Dev Containers: Open Folder in Containers...`,打开刚刚克隆的仓库。 +5. 然后 show log,可以看到 vscode 在下载一系列依赖 +6. 此时 docker 中会多了一个名为 vscode 的 volume +7. 下载完成后,docker 中会多出一个名为 mcr.microsoft.com/devcontainers/rust 的 images (大小为 2.2GB) +8. 同时也会多出一个名为 gallant_ganguly 的 containers,它的 images 就是 mcr.microsoft.com/devcontainers/rust +9. 此时 vscode 应该处于容器里面了,目录就是刚刚克隆的仓库。 + +> 需要注意的是,vscode 的本机 workspace 不支持容器中的目录! + +在目录中执行以下命令 + +```sh +# 当前目录是 /workspaces/vscode-remote-try-rust + +# 初次进入容器时,不是 root 用户,并且此时默认没有 root 密码 +# 所以需要设置初始密码 +sudo passwd root + +# 默认的用户是 vscode +whoami + +cd .. +# 进入 /workspaces + +sudo git clone https://github.com/Linhieng/learn-rust.git +# 刚刚克隆的 vscode-remote-try-rust 项目没有用,它只是用来帮助下载 rust 镜像的 +# 实际学习中,使用自己的仓库。 + +sudo chown -R vscode:vscode learn-rust/ +# 将所有者改为 vscode + +cd learn-rust +code . +# 打开新窗口,注意此时还是使用的系统全局代理,而不是 vscode 中的 http.proxy + +cargo run +# 成功运行 +``` + +好了,到这里就可以成功运行 rust 了。后面的内容就是 linux 的知识了,不在这里记录! diff --git a/rust/docs/begin.md b/rust/docs/begin.md new file mode 100644 index 0000000..9e2fed8 --- /dev/null +++ b/rust/docs/begin.md @@ -0,0 +1,223 @@ +# 学习 rust + +由于是学习,所以格式相关内容就按着喜欢的样式来! + +## 语言核心概念 + + 变量 + 变量绑定、所有权 + 变量可变性、常量 + 变量遮蔽(shadowing) + 变量解构 + 类型 + 有符号整数、无符号整数、有理数、复数 + 字符串字面量、字符串切片 + 布尔 true false + 字符(Unicode 字符) + 单元类型 () + 数值类型 + 运算符重载 + 整形溢出: + wrapping_ + checked_ + overflowing_ + saturating_ + 浮点数陷阱。0.1 + 0.2、f32 和 f64 + NaN。不可比较,不可运算。 + 数学运算 + - * / % + 位运算 & | ! ^ << >> (有无符号根据类型判断) + 序列 range + + +## cargo 和命令行 + +- 可参考资料 + + - [设置 - Cargo 手册 中文版 (rustwiki.org)] + - [Cargo 使用指南 - Rust语言圣经(Rust Course)] + +cargo 包管理器 + + 总结: +```sh + cargo new + cargo run [--release] + cargo build [--release] + cargo check + cargo add +``` + + 详细: + +```sh + cargo new world_hello + # 创建新项目 + + cargo run + # 运行项目 + # 等同于 + cargo build # 编译 + ./target/debug/world_hello # 运行 + # 添加 --release 提高性能(优化) + cargo run --release + cargo build --release + ./target/release/world_hello # 项目名为 world_hello + + cargo check + # 检查代码能否编译通过(快速) + +``` + Cargo.toml 和 Cargo.lock + + Cargo.toml 是 cargo 特有的项目数据描述文件 + Cargo.lock 文件是 cargo 工具根据同一项目的 toml 文件生成的项目依赖详细清单 + TOML: Tom's Obvious Minimal Language + +rustc + +```sh + rustc + rustc --version +``` + +## 读懂代码 + +代码片段: + +```rs + fn main() { + let x =define_x(); + let y = define_y(); + println!("{}, world", x); + println!("{}, world", y); + let mut z = 1; + println!("{}", z); + z = 2; + let z = z; + println!("{}", z); + test_unused_variables(); + + let (mut i, j) = (1, 2); + assert_eq!(i, 1); + i = 2; + assert_eq!(i, 2); + assert_eq!(j, 2); + } + fn define_x() -> String { + let x = "hello".to_string(); + return x + } + fn define_y() -> &'static str { + let x = "hello"; + x + } + #[allow(unused_variables)] + fn test_unused_variables() { + let x = 123; + } +``` + +读懂代码: + +```rs + let _something = "42".parse::().expect("Not a number!"); +``` + +读懂代码 + +```rs + fn main() { + assert_eq!(9, u8::MAX.wrapping_add(10)); + assert_eq!(None, u8::MAX.checked_add(10)); + assert_eq!((9, true), u8::MAX.overflowing_add(10)); + assert_eq!(255, u8::MAX.saturating_add(10)); + // println!("{}", 10_u8.checked_add(10)); + println!("{:?}", 10_u8.checked_add(10)); // Option + } +``` + +读懂代码 + +```rs + fn main() { + let abc: (f32, f32, f32) = (0.1, 0.2, 0.3); + let xyz: (f64, f64, f64) = (0.1, 0.2, 0.3); + println!("abc (f32)"); + println!(" 0.1 + 0.2: {:x}", (abc.0 + abc.1).to_bits()); + println!(" 0.3: {:x}", (abc.2).to_bits()); + println!(); + println!("xyz (f64)"); + println!(" 0.1 + 0.2: {:x}", (xyz.0 + xyz.1).to_bits()); + println!(" 0.3: {:x}", (xyz.2).to_bits()); + println!(); + assert!(abc.0 + abc.1 == abc.2); // 不报错 + assert!(xyz.0 + xyz.1 == xyz.2); // 报错 + } +``` + +看懂代码 + +```rs + fn main() { + let x = (-1.0_f32).sqrt(); + assert_ne!(x, x); // NaN != NaN + if x.is_nan() { + println!("未定义的数学行为"); + } + } +``` + + 看懂代码 +```rs + fn main() { + // 编译器会进行自动推导,给予twenty i32的类型 + let twenty = 20; + // 类型标注 + let twenty_one: i32 = 21; + // 通过类型后缀的方式进行类型标注:22是i32类型 + let twenty_two = 22i32; + // 只有同样类型,才能运算 + let addition = twenty + twenty_one + twenty_two; + println!( + "{} + {} + {} = {}", + twenty, twenty_one, twenty_two, addition + ); + // 对于较长的数字,可以用_进行分割,提升可读性 + let one_million: i64 = 1_000_000; + println!("{}", one_million.pow(2)); + // 定义一个f32数组,其中42.0会自动被推导为f32类型 + let forty_twos = [42.0, 42f32, 42.0_f32]; + // 打印数组中第一个值,并控制小数位为2位 + println!("{:.2}", forty_twos[0]); + } +``` + +看懂代码 + +```rs + fn main() { + for i in 1..5 { + print!("{} ", i); + } + println!(""); // 1 2 3 4 + for i in 1..=5 { + print!("{} ", i); + } + println!(""); // 1 2 3 4 5 + for c in 'a'..'f' { + print!("{} ", c); + } + println!(""); // a b c d e + for c in 'a'..='f' { + print!("{} ", c); + } + println!(""); // a b c d e f + } +``` + + + + + +[设置 - Cargo 手册 中文版 (rustwiki.org)]: https://rustwiki.org/zh-CN/cargo/reference/config.html +[Cargo 使用指南 - Rust语言圣经(Rust Course)]: https://course.rs/cargo/intro.html diff --git a/rust/src/main.rs b/rust/src/main.rs new file mode 100644 index 0000000..1f05d2d --- /dev/null +++ b/rust/src/main.rs @@ -0,0 +1,18 @@ +fn main() { + for i in 1..5 { + print!("{} ", i); + } + println!(""); // 1 2 3 4 + for i in 1..=5 { + print!("{} ", i); + } + println!(""); // 1 2 3 4 5 + for c in 'a'..'f' { + print!("{} ", c); + } + println!(""); // a b c d e + for c in 'a'..='f' { + print!("{} ", c); + } + println!(""); // a b c d e f +}