Rust Learning
Rust Learning
References
- Julia、Rust、F#、Go编程语言游览和感想
- Rust, Julia, and Go_ Disruptive New Programming Languages Changing the Face of C
- 新兴的函数式编程语言(如 Elixir 或 Elm)
- 从实际应用角度来看,Rust更偏向于底层,旨在替换C语言与C++,Golang旨在替换Java与C#。
- Rust语言本身不依赖于虚拟机与GC,没有运行时,跨平台,主要靠一套所有权、生命周期、类型系统维护着语言的本身,语言高度抽象。
- Golang 语言需要依赖于GC,自动垃圾回收,自带协程,快速编译,跨平台。
- Rust 是一门入门门槛较高的语言,所有权与生命周期阻碍了不知多少的编程者。而go语言,入门较容易,学过类C语言同学,基本看一下语法就能入手写代码。
- Rust Book
- Rust by Example
- Rustlings Small exercises to get you used to reading and writing Rust code!
- The Rust Programming Language
- The Cargo Book
- The Rust Playground
- Rust.cc Rust语言中文社区
- Rust Force CN
- Rust in Motion Need to buy $39.99
Web
- Rocket is a web framework for Rust with flexibility, usability, or type safety.
- IRON extensible web framework for rust
LISP
- Ketos is a Lisp dialect functional programming language.
- Carp A statically typed lisp, without a GC, for real-time applications.
GUI
- Are we GUI Yet? The state of building user interfaces in Rust.
- conrod An easy-to-use, 2D GUI library written entirely in Rust.
- druid Data-oriented Rust UI design toolkit.
- libui-rs Rust bindings to the minimalist, native, cross-platform UI toolkit
libui
Other
- [oeasy]教您玩转rust编程视频教程
- 使用Rust编写操作系统(一):独立式可执行程序
- 不能使用线程、文件、堆内存、网络、随机数、标准输出,或其它任何需要操作系统抽象和特定硬件的特性;
- 可以使用迭代器、闭包、模式匹配、Option、Result、字符串格式化,当然还有所有权系统。
- 需要创建一个独立于操作系统的可执行程序,被称作独立式可执行程序(freestanding executable)或裸机程序(bare-metal executable)。
- 独立式可执行程序并不能访问Rust运行时或crt0库,需要定义自己的入口点,即重写整个crt0库和它定义的入口点。
- Rust与go在网上吵的比较大区别是,Rust有泛型,而Go没有。
- 做网络服务选Go, 上手比较简单。做系统用Rust, 它就是未来的系统语言。
- 将Rust编译成库
- Rust初步(六):在C#中使用Rust组件
- Rust vs. C++:性能大比拼
- 如何利用科大源提速Cargo和Rust
- Writing an OS in Rust
- CS140E: Operating Systems Design and Implementation
- 一个Rust OS的专栏
- Julia 是新晋发布1.0版本的科学计算类语言,号称兼具C++、python、matlab的优点。
- 孩子的编程语言
- V 语言强势登顶 GitHub TOP1,难道要取 Go 而代之?
- vlang
Learn web
“优于 std 的”工具箱
- 在几乎所有方面,crossbeam 都比 std::sync::mpsc 更适合线程间通信,并且最终可能会合并到 std 中。
- parking_lot 在几乎所有方面都具有优于 std::sync::Mutex 的 mutex 实现,并且某一天可能合并到标准库中。它还提供了其他许多有用的同步原语。
- 与 Vec相比,bytes 是一种更健壮且通常性能更高的字节处理方式。
- 如果你要进行底层网络优化,socket2 会是你的最终选项。
锦上添花
- fern 是一种自定义和美化日志记录输出的简单方法。我们使用它来保持日志的可读性和内部标准化。
- structopt 是你一直梦寐以求的 CLI 参数处理方式。除非你的依赖项几乎没有,否则没有理由不使用它。
Cargo 经典传奇
- cargo-release 使我们能够轻松减少内部版本。
- cargo-udeps 可以识别未使用的依赖项,并尽可能减少我们的构建时间。
- cargo tree(最近集成进了 cargo)显示了一个依赖树,它在许多方面都很有用,但主要用于找出最小化依赖项的途径。
- cargo-geiger 帮助我们快速评估外部依赖,以解决可能的安全性(或正确性)问题。
- cargo-flamegraph 在跟踪代码中的性能热点时给了我们巨大的帮助。
持续测试
- 我们使用谷歌的 Cloud Builder 来运行 CI 构建,因为我们的基础架构栈主要基于 GCP 构建,并且可以轻松调整构建机器规格和自定义构建映像。每次提交都会触发它,并运行 cargo clippy 和 cargo build。我们将 -D warnings 传递给编译器,以将警告升级为错误,确保我们的更改不会在可怜的同事下次拉取更改时劈头盖脸迎来大堆 rustc 警告。
- 为了缩短配置项构建时间,我们将 target 和.cargo 目录缓存在 Cloud Storage 中,以便下次可以下载并增量构建。
国内镜像源
# 放到 `$HOME/.cargo/config` 文件中
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
# 替换成你偏好的镜像源
replace-with = 'sjtu'
# 清华大学
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
# 中国科学技术大学
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"
# 上海交通大学
[source.sjtu]
registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index"
# rustcc社区
[source.rustcc]
registry = "git://crates.rustcc.cn/crates.io-index"
Key points
- 理解所有权:What is Ownership
- Copy
- Move
- Clone
- 理解引用和借用:References and Borrowing
- & 引用
- (&) 借用
- We call having references as function parameters borrowing
- 我们称“将引用作为函数参数”为“借用”
- * 解引用
这里遇到一个实例:
use std::fs;
fn main() {
println!("Start modifies");
let paths = fs::read_dir("./").unwrap();
let c = paths.count();
println!("Count: {}", c);
}
// 这样就是 work 的
use std::fs;
fn main() {
println!("Start modifies");
let paths = fs::read_dir("./").unwrap();
for path in paths {
println!("Name: {}", path.unwrap().path().display())
}
}
// 这样也是 work 的
use std::fs;
fn main() {
println!("Start modifies");
let paths = fs::read_dir("./").unwrap();
for path in paths {
println!("Name: {}", path.unwrap().path().display())
}
let c = paths.count();
println!("Count: {}", c);
}
// 但是两个放一起就不 work 了,但我也不想再弄一个变量,于是就报错了。
结果找到原因是 Iterate 不同于数组容器只能使用一次,所以改为如下即可:
pub fn list_of_path(path: &str) -> vec::Vec<String> {
let paths = fs::read_dir(path).unwrap();
return paths.map(|path|{
let name = path.unwrap().path().display().to_string();
println!("Name: {}", name);
return name;
}).collect::<Vec<String>>();
}
let paths = list_of_path(S);
let c = paths.len();
assert_eq!(c, 7);
for p in paths {
assert!(p.len() > 0);
println!("Name: {}", p);
}
数据竞争
对于所有的类型T和任意的生命周期参数‘a,都能衍生出两种类型:&‘a T 和 &mut ‘a T。
&‘a T 相当于T的读取器,持有T的读锁, &mut ‘a T 相当于T的写入器,持有T的写锁。
编译器里有一个工具borrowck,在编译时会自动检查这两种类型的使用情况,如果有非法的使用,就报错,不让你编译通过。同样地,当你手中还持有着对一个值的引用时,编译器不允许将其移动或者销毁。这样,就杜绝了野指针现象和数据竞争问题。
let rb0 = &b;
let rb1 = &mut b;
值传递
Rust 的默认的值的传递是:转移。不管是赋值还是函数调用时的参数和返回值,都是这样。
分类体系(taxonomy)
开放的分类,使用泛型;封闭的分类,使用枚举(ADT)。