加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
rust.org 17.60 KB
一键复制 编辑 原始数据 按行查看 历史
Sniper 提交于 2022-10-08 14:45 . update network.

total

install

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

windows :

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

start

rustc hello.rs

cargo

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 mirrors

~/.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"

stady

通过例子学 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

rust-analyzer

安装: 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

emacs

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/

usb

https://lib.rs/crates/usbapi https://github.com/dcuddeback/libusb-rs

api lib/docs

https://lib.rs/ https://docs.rs/

tip

所有权

借用(Borrowing) ,获取变量的引用,称之为借用(borrowing) 我们将获取引用作为函数参数称为 借用(borrowing) 借用规则如下: 同一时刻,你只能拥有要么一个可变引用, 要么任意多个不可变引用 引用必须总是有效的

函数和方法

关联函数 这种定义在 impl 中且没有 self 的函数被称之为 关联函数 : 因为它没有 self,不能用 f.read() 的形式调用, 因此它是一个函数而不是方法,它又在impl 中,与结构体紧密关联,因此称为关联函数。

trait

使用特征作为函数参数

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太厉害了,电脑再也不会卡",
        )
    }
}

特征对象(trait object)

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>;
}

函数指针和闭包 closure

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) 不可变借用,不可以改变引用变量的值,但不会释放该变量,所以可以运行多次

lifetime

&’static 和 T: ‘static

  • 第一条规则是每一个是引用的参数都有它自己的生命周期参数
  • 第二条规则是如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数
  • 第三条规则是如果是有多个输入生命周期参数的方法,而其中一个参数是 &self 或 &mut self, 那么所有输出生命周期参数被赋予 self 的生命周期。
  • 其他情况下,生命周期必须有明确的注解

error

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

FFI

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

copy/clone

https://zhuanlan.zhihu.com/p/21730929 对于struct和enum类型,不会自动实现Copy trait。 而且只有当struct和enum内部每个元素都是Copy类型的时候,编译器才允许我们针对此类型实现Copy trait。

#[derive(Copy, Clone)]
struct MyStruct(i32);

& 和 ref

fn main() {
    let mut a: i32 = 111;

    let b = &a;
    println!("{}", *b); //111

    let ref c = a;
    println!("{}", *c); //111
}

struct

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
}

match

模式匹配 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/cell/RefCell

Rc 和 Arc 的区别在于,后者是原子化实现的引用计数,因此是线程安全的,可以用于多线程中共享数据。 这两者都是只读的,如果想要实现内部数据可修改,必须配合内部可变性 RefCell 或者互斥锁 Mutex 来一起使用。

get_mut/make_mut

println

#[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);

string

&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**

marco

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++));
}

减少rust编译后程序体积

cargo build –release

strip 命令 strip -s target/release/testGui

在Cargo.toml中新增下面配置

开启编译优化等级s/z [profile.release] opt-level = ‘z’

开启 LTO [profile.release] lto = true

rustlings

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

proxy/stunnel

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
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化