https://www.rust-lang.org curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs | sh rustc –version cargo –version 卸载 rustup self uninstall
通过 rustup 安装 stable版本 $ rustup install stable
设置stable为默认的版本 $ rustup default stable
使用国内镜像安装 https://www.cnblogs.com/hustcpp/p/12341098.html
curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs > rust.sh
将 RUSTUP_UPDATE_ROOT 修改为
# If RUSTUP_UPDATE_ROOT is unset or empty, default it.
RUSTUP_UPDATE_ROOT="${RUSTUP_UPDATE_ROOT:-https://static.rust-lang.org/rustup}"
RUSTUP_UPDATE_ROOT="https://mirrors.ustc.edu.cn/rust-static/rustup"
修改环境变量
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup
bash rust.sh
https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/
提示安装好了之后,创建文件D:\Rust\cargo\config,并加入如下内容:
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'ustc'
[source.ustc]
registry = "git://http://mirrors.ustc.edu.cn/crates.io-index"
[target.x86_64-pc-windows-gnu]
linker = "C:\\msys64\\mingw64\\bin\\gcc.exe"
ar = "C:\\msys64\\mingw64\\bin\\ar.exe"
检查一下环境变量PATH中是否加入了D:\Rust\cargo\bin路径。 如果加了,在windows的cmd里就可以直接使用cargo和rustup命令了。
如果 提示没有默认的 toolchain 那么 install: rustup install stable-x86_64-pc-windows-gnu
将 gnu 版设为 default rustup default stable-x86_64-pc-windows-gnu
rustc hello.rs
cargo build:编译 cargo run :执行 cargo clippy: 类似eslint,lint工具检查代码可以优化的地方 cargo fmt: 类似go fmt,代码格式化 cargo tree: 查看第三方库的版本和依赖关系 cargo bench: 运行benchmark(基准测试,性能测试) cargo udeps(第三方): 检查项目中未使用的依赖 另外 cargo build/run –release 使用 release 编译会比默认的 debug 编译性能提升 10 倍以上,但是 release 缺点是编译速度较慢,而且不会显示 panic backtrace 的具体行号
cargo new hello_world cd hello_world
cargo check cargo build –release cargo clean cargo install cargo uninstall
安装插件: cargo install cargo-edit cargo add tui
. ├── Cargo.toml ├── examples │ └── test.rs ├── LICENSE ├── README.md └── src └── lib.rs cargo run –example test
~/.cargo 目录 创建文件config 内容如下
[source.crates-io] registry = "https://github.com/rust-lang/crates.io-index" # 指定镜像 # replace-with = 'sjtu' replace-with = 'tuna' # 清华大学 [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 = "https://code.aliyun.com/rustcc/crates.io-index.git"
通过例子学 Rust: https://rustwiki.org/zh-CN/rust-by-example/ https://gitee.com/rust-china https://github.com/rust-lang/rustlings https://github.com/ctjhoa/rust-learning https://github.com/rust-unofficial/awesome-rust 标准库:https://doc.rust-lang.org/std/index.html
安装: rustup component add rust-analyzer-preview rust-analyzer会装到以下路径: ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rust-analyzer
mkdir -p ~/.local/bin
curl -L https://github.com/rust-analyzer/rust-analyzer/releases/latest/download/rust-analyzer-x86_64-unknown-linux-gnu.gz |\
gunzip -c - > ~/.local/bin/rust-analyzer
chmod +x ~/.local/bin/rust-analyzer
git clone https://github.com/rust-analyzer/rust-analyzer.git –depth 1 cd rust-analyzer cargo xtask install –server
https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/
https://github.com/racer-rust/emacs-racer https://github.com/racer-rust/racer $ rustup toolchain add nightly $ rustup component add rust-src $ cargo +nightly install racer https://github.crookster.org/my-emacs-rust-language-config/
https://lib.rs/crates/usbapi https://github.com/dcuddeback/libusb-rs
https://lib.rs/ https://docs.rs/
借用(Borrowing) ,获取变量的引用,称之为借用(borrowing) 我们将获取引用作为函数参数称为 借用(borrowing) 借用规则如下: 同一时刻,你只能拥有要么一个可变引用, 要么任意多个不可变引用 引用必须总是有效的
关联函数
这种定义在 impl 中且没有 self 的函数被称之为 关联函数 : 因为它没有 self,不能用 f.read() 的形式调用,
因此它是一个函数而不是方法,它又在impl 中,与结构体紧密关联,因此称为关联函数。
pub fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
impl Summary,它的意思是 实现了Summary特征 的 item 参数。 你可以使用任何实现了 Summary 特征的类型作为该函数的参数, 同时在函数体内,还可以调用该特征的方法,例如 summarize 方法。 具体的说,可以传递 Post 或 Weibo 的实例来作为参数, 而其它类如 String 或者 i32 的类型则不能用做该函数的参数,因为它们没有实现 Summary 特征。
特征约束(trait bound)
pub fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
impl<T: Display> ToString for T {
// --snip--
}
函数返回中的 impl Trait
fn returns_summarizable() -> impl Summary {
Weibo {
username: String::from("sunface"),
content: String::from(
"m1 max太厉害了,电脑再也不会卡",
)
}
}
https://course.rs/basic/trait/trait-object.html
trait Draw {
fn draw(&self) -> String;
}
impl Draw for u8 {
fn draw(&self) -> String {
format!("u8: {}", *self)
}
}
impl Draw for f64 {
fn draw(&self) -> String {
format!("f64: {}", *self)
}
}
fn draw1(x: Box<dyn Draw>) {
x.draw();
}
fn draw2(x: &dyn Draw) {
x.draw();
}
fn main() {
let x = 1.1f64;
// do_something(&x);
let y = 8u8;
draw1(Box::new(x));
draw1(Box::new(y));
draw2(&x);
draw2(&y);
}
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
https://course.rs/advance/functional-programing/closure.html
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
query: T,
value: Option<u32>,
}
T: Fn(u32) -> u32 意味着 query 的类型是 T,该类型必须实现了相应的闭包特征 Fn(u32) -> u32。
struct Cacher<T,E>
where
T: Fn(E) -> E,
E: Copy
{
query: T,
value: Option<E>,
}
impl<T,E> Cacher<T,E>
where
T: Fn(E) -> E,
E: Copy
{
fn new(query: T) -> Cacher<T,E> {
Cacher {
query,
value: None,
}
}
fn value(&mut self, arg: E) -> E {
match self.value {
Some(v) => v,
None => {
let v = (self.query)(arg);
self.value = Some(v);
v
}
}
}
}
#[test]
fn call_with_different_values() {
let mut c = Cacher::new(|a| a);
let v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 1);
}
move - 使闭包获取其所捕获项的所有权
Fn、FnMut、FnOnce
FnOnce FnOnce(self) 获取变量的所有权,在其作用域内有效,所以只能运行一次;
FnMut FnMut(&mut self) 可变借用,可以改变引用变量的值,但不会释放该变量,所以可以运行多次
Fn Fn(&self) 不可变借用,不可以改变引用变量的值,但不会释放该变量,所以可以运行多次
&’static 和 T: ‘static
https://github.com/baoyachi/rust-error-handle 自定义的Error
source()此错误的低级源,如果内部有错误类型Err返回:Some(e),如果没有返回:None。
如果当前Error是低级别的Error,并没有子Error,需要返回None。介于其本身默认有返回值None,可以不覆盖该方法。 如果当前Error包含子Error,需要返回子Error:Some(err),需要覆盖该方法。
use std::error::Error;
///自定义类型 Error,实现std::fmt::Debug的trait
#[derive(Debug)]
struct CustomError {
err: ChildError,
}
///实现Display的trait,并实现fmt方法
impl std::fmt::Display for CustomError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "CustomError is here!")
}
}
///实现Error的trait,因为有子Error:ChildError,需要覆盖source()方法,返回Some(err)
impl std::error::Error for CustomError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.err)
}
}
自定义Error转换:From
foreign function interface https://doc.rust-lang.org/nomicon/ffi.html https://rustcc.cn/article?id=3518647e-51c8-4216-a267-4690b2597f99
#[cfg(target_os = "windows")]
mod os {
// windows相关结构方法代码
...
}
#[cfg(target_os = "linux")]
mod os {
// linux相关结构方法代码
...
}
除了按系统类型条件编译外,rust还支持以下类型条件: debug_assertions - 若没有开启编译优化时就会成立。 target_arch = “…” - 目标平台的CPU架构,包括但不限于x86, x86_64, mips, powerpc, arm或aarch64。 target_endian = “…” - 目标平台的大小端,包括big和little。 target_env = “…” - 表示使用的运行库,比如musl表示使用的是MUSL的libc实现, msvc表示使用微软的MSVC,gnu表示使用GNU的实现。 但在部分平台这个数据是空的。 target_family = “…” - 表示目标操作系统的类别,比如windows和unix。这个属性可以直接作为条件使用,如#[unix],#[cfg(unix)]。 target_os = “…” - 目标操作系统,包括但不限于windows, macos, ios, linux, android, freebsd, dragonfly, bitrig, openbsd, netbsd。 target_pointer_width = “…” - 目标平台的指针宽度,一般就是32或64。 target_vendor = “…” - 生产商,例如apple, pc或大多数Linux系统的unknown。 test - 当启动了单元测试时(即编译时加了–test参数,或使用cargo test)。 还可以根据一个条件去设置另一个条件,使用cfg_attr,如
// 这个函数仅当操作系统不是Linux 时才会编译
#[cfg(not(target_os = "linux"))]
fn not_linux() {
println!("You are not running linux!");
}
// 这个函数当为macos**或者**ios时才会编译
#[cfg(any(target_os = "macos", target_os="ios"))]
fn you_are_apple {
println!("You are running macos or ios");
}
// 这个函数当为32位的Unix系统时才会编译
#[cfg(all(unix, target_pointer_width = "32"))]
fn on_32bit_unix() {
println!("You are running 32 bit unix");
}
#[cfg(some_condition)]
fn conditional_function() {
println!("condition met!")
}
fn main() {
conditional_function();
}
cargo.toml
[features]
some_condition = []
$ cargo build --features some_condition
https://zhuanlan.zhihu.com/p/21730929 对于struct和enum类型,不会自动实现Copy trait。 而且只有当struct和enum内部每个元素都是Copy类型的时候,编译器才允许我们针对此类型实现Copy trait。
#[derive(Copy, Clone)]
struct MyStruct(i32);
fn main() {
let mut a: i32 = 111;
let b = &a;
println!("{}", *b); //111
let ref c = a;
println!("{}", *c); //111
}
struct Student {
name: String,
chinese: u32,
math: u32,
science: u32,
english: u32
}
fn main() {
let stu1 = Student {
name: String::from("yuyoubei"),
chinese: 90,
math: 100,
science: 95,
english: 95,
};
println!("{} {} {} {} {}", stu1.name, stu1.chinese, stu1.math, stu1.science, stu1.english); // 输出 yuyoubei 90 100 95 95
let stu2 = Student {
name: String::from("yihan"),
chinese: 99,
..stu1
};
println!("{} {} {} {} {}", stu2.name, stu2.chinese, stu2.math, stu2.science, stu2.english); // 输出 yihan 99 100 95 95
let stu3 = Student {
..stu2
};
println!("{} {} {} {} {}", stu3.name, stu3.chinese, stu3.math, stu3.science, stu3.english); // 输出 yihan 99 100 95 95
}
模式匹配 guard 模式后面可以跟着一个条件表达式,叫做 “guard”:
let n = 3;
match n {
n if n > 2 => println!("> 2"),
n if n < 3 => println!("< 3"),
_ => println!("some else"),
};
// 在 match-arm的 => 前面可以有一个if 条件,即使 match 匹配,还可以通过 if 进行过滤
let n = 4;
match n {
x => println!(" x = {}",x),
};
// x 被赋值 n ,即:let x = n。
let number = 13;
println!("Tell me about {}", number);
match number {
1 => println!("One!"),
2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
13...19 => println!("A teen"),
_ => println!("Ain't special"),
}
fn check_info(info: Info) -> bool {
if let (Some(name), Some(addr), Some(phone)) = (info.name, info.addr, info.phone) {
println!("name{:?},addr:{:?},phone:{:?}", name, addr, phone);
return true;
}
false
}
Rc 和 Arc 的区别在于,后者是原子化实现的引用计数,因此是线程安全的,可以用于多线程中共享数据。 这两者都是只读的,如果想要实现内部数据可修改,必须配合内部可变性 RefCell 或者互斥锁 Mutex 来一起使用。
#[derive(Debug)]
struct Foo {
x: i32,
y: i32,
}
let foo = Foo { x: 1, y: 2 };
println!("Simple debug:\n{:?}", foo);
println!("Pretty debug:\n{:#?}", foo);
Simple debug:
Foo { x: 1, y: 2 }
Pretty debug:
Foo {
x: 1,
y: 2,
}
格式化符号是{:x}、{:X} {:02X}表示输出的长度为2,如果不足两位,则补0。
let aaa = 0xb;
println!("test:{:x}", aaa);
&str -> String–| String::from(s) or s.to_string() or s.to_owned() &str -> &[u8]—| s.as_bytes() &str -> Vec<u8>-| s.as_bytes().to_vec() or s.as_bytes().to_owned() String -> &str—-| &s if possible* else s.as_str() String -> &[u8]—| s.as_bytes() String -> Vec<u8>-| s.into_bytes() &[u8] -> &str—-| s.to_vec() or s.to_owned() &[u8] -> String–| std::str::from_utf8(s).unwrap(), but don’t** &[u8] -> Vec<u8>-| String::from_utf8(s).unwrap(), but don’t** Vec<u8> -> &str—-| &s if possible* else s.as_slice() Vec<u8> -> String–| std::str::from_utf8(&s).unwrap(), but don’t** Vec<u8> -> &[u8]—| String::from_utf8(s).unwrap(), but don’t**
item :例如 函数、结构、模块等等 block : 代码块(例如 表达式或者复制代码块,用花括号包起来) stmt:赋值语句(statement) pat :Pattern ,匹配 expr :表达式,expression : 1 + 2 ty:类型 ident:标记,识别码 path:路径(例如:foo, ::std::men::replace,transmute::<_,int>,…) meta:元项目;在 #[…] 和 #![…] 属性里面的内容 tt:单 token tree : 1, 2
macro_rules! some_rules {
// 把“更具体”的规则放在前面
($a:ident++) => {
{
$a = $a+1;
$a
}
};
($e:expr) => {
$e
};
}
fn main() {
let mut a = 0;
println!("{}", some_rules!(a++));
}
cargo build –release
strip 命令 strip -s target/release/testGui
在Cargo.toml中新增下面配置
开启编译优化等级s/z [profile.release] opt-level = ‘z’
开启 LTO [profile.release] lto = true
error5.rs error6.rs enums3.rs generics3.rs option2.rs option3.rs box1.rs iterators2.rs iterators3.rs threads1.rs macros3.rs macros4.rs quiz4.rs from_str.rs as_ref_mut.rs try_from_into.rs advanced_errs1.rs advanced_errs2.rs
https://ghproxy.com/
# 全局代理设置
git config --global http.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:7890
# 只对GitHub进行代理
git config --global http.https://github.com.proxy http://127.0.0.1:7890
git config --global https.https://github.com.proxy http://127.0.0.1:7890
git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
git config --global https.https://github.com.proxy socks5://127.0.0.1:1080
#取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy
# 查看已有配置
git config --global -l
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。