DAILY DOCDAILY DOC
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
  • rust

    • Rust
    • add
    • 属性(attributes)
    • cargo issue
    • cli
    • build.rs
    • Enums
    • eventEmitter(rust)
    • 格式化输出 std::fmt
    • rust iterator
    • rust 学习计划
    • 生命周期(lifetime)
    • Linked List
    • log
    • macros
    • mem::size_of
    • niche optimization
    • Rust 所有权
    • 模式匹配(pattern matching)
    • module system
    • result & option
    • .rust-analyzer.json
    • rust startup
    • rust-test
    • 可见性(visibility)
    • cargo
    • toml

module system

  • Packages: A Cargo feature that lets you build, test, and share crates
  • Crates: A tree of modules that produces a library or executable
  • Modules and use: Let you control the organization, scope, and privacy of paths
  • Paths: A way of naming an item, such as a struct, function, or module

package

A package can contain multiple binary crates and optionally one library crate. At least on crate.

├── Cargo.lock
├── Cargo.toml
├── src
│   ├── bin
│   │   └── a.rs
│   │   └── b.rs
│   ├── lib.rs
│   └── main.rs

Crates

  • binary crate
  • library crate

Modules

  • pub
  • mod
  • use
  • as

visibility

  • private(default)
  • pub(crate)
  • pub(in path)
  • pub use

xxx/mod.rsvs xxx.rs

  • Inline, within curly brackets that replace the semicolon following mod garden
  • In the file src/garden.rs
  • In the file src/garden/mod.rs
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── A.rs
│   ├── B
│   │   └── mod.rs
│   ├── bin
│   │   └── a.rs
│   ├── lib.rs
│   └── main.rs

details
use init_rust_project::echo;
mod A;
mod B;

fn main() {
    println!("Hello, world!");
    echo("Hi World");
    A::a();
    let one = A::ONE;
    B::echo();
}

Path

  • absolute path crate
  • relative path super self

details
use init_rust_project::echo;
use A::ONE;
use B::echo as echo2;
mod A;
mod B;

fn main() {
    println!("Hello, world!");
    echo("Hi World");
    A::a();
    crate::A::a();

    let one = ONE;
    B::echo();
    self::B::echo();

    echo2();
}

fn echo_from_main() {
    //
}
mod MainModule {

    fn test() {
        super::echo_from_main();
    }
}

workspace

multi packages

Root dir cargo.toml

[workspace]
lib_add = {path ="./lib_add"}

setup project

  • cargo new xxx
  • Fill out cargo.toml
  • Split out module
  • Add test
    • unit
    • integration
    • doc
    • bench
    • examples
  • Publish to crates.io

target 目录分析

在 Rust 中使用 cargo build 命令时,生成的目标目录(通常是 target)包含了编译输出和构建过程中产生的各种文件。以下是 target/debug 目录结构的分析:

└── debug
    ├── build
    ├── deps
    ├── examples
    ├── incremental
    ├── liblib_add.d
    ├── liblib_add.rlib
    ├── rust-workspace
    └── rust-workspace.d

目录与文件分析

  1. build:

    • 该目录包含了构建过程中生成的中间文件和依赖项信息。
    • build 目录用于存放构建脚本(如 build.rs)的输出及其依赖关系。
  2. deps:

    • 该目录包含编译后的库和二进制文件,通常是 .rlib 和 .d 文件。
    • 这些文件是构建过程中生成的所有依赖库的编译结果,命名格式通常为 lib{crate-name}-{hash}.rlib 或 {crate-name}-{hash}.d。
  3. examples:

    • 该目录包含编译后的示例程序。
    • Rust 项目可以在 examples 目录下包含示例代码,这些示例代码会被单独编译并放在 target/debug/examples 目录中。
  4. incremental:

    • 该目录用于存放增量编译的缓存文件。
    • Rust 的增量编译功能使得只重新编译发生变化的部分代码,从而加快编译速度。
    • incremental 目录中存放的就是这些缓存文件。
  5. liblib_add.d:

    • .d 文件是依赖关系文件,通常包含了源文件之间的依赖关系信息,用于增量编译过程中决定哪些文件需要重新编译。
  6. liblib_add.rlib:

    • .rlib 文件是 Rust 编译生成的库文件,包含了编译后的中间代码,可以被其他 Rust 项目链接和使用。
    • liblib_add.rlib 是 lib_add 库的编译结果,包含了该库的所有代码。
  7. rust-workspace:

    • 该文件是编译后的 rust-workspace 二进制文件。
    • 如果 rust-workspace 是一个可执行项目,这里存放的就是最终的可执行文件。
  8. rust-workspace.d: - .d 文件与前面的 liblib_add.d 类似,包含了 rust-workspace 可执行文件的依赖关系信息。


build.rs

cargo-build-scripts

details

A build.rs script in a Rust project is used to perform custom build steps before the main compilation. These steps might include generating code, compiling other languages, or setting environment variables. The output from build.rs can sometimes be confusing if it doesn't show up as expected. Here’s how to properly write and debug a build.rs file.

Example of a Basic build.rs File

Here’s a simple example of a build.rs file that prints messages and sets environment variables:

use std::env;
use std::fs::File;
use std::io::Write;

fn main() {
    // Print messages to the build output
    println!("Hello from build.rs!");

    // Print a cargo directive to rerun the build script if build.rs changes
    println!("cargo:rerun-if-changed=build.rs");

    // Print a cargo directive to set an environment variable
    println!("cargo:rustc-env=MY_ENV_VAR=Hello from build.rs!");

    // Write to a file for debugging purposes
    let mut file = File::create("build_output.txt").expect("Could not create file");
    writeln!(file, "Hello from build.rs!").expect("Could not write to file");

    // Example of setting an environment variable for the Rust compiler
    env::set_var("MY_BUILD_VAR", "Some value");
}

创建 examples 目录及编写示例代码

details

examples 目录下的文件是用户在项目中专门为编写示例程序而创建的。这些示例程序可以用来展示如何使用你的库、验证特定功能或提供具体的使用案例。

1. 创建 examples 目录

首先,在你的项目根目录下创建一个名为 examples 的目录:

mkdir examples

2. 编写示例程序

在 examples 目录下,你可以创建多个 Rust 源文件,每个文件都代表一个独立的示例程序。例如,创建一个名为 hello_world.rs 的文件:

touch examples/hello_world.rs

在这个文件中编写你的示例代码:

fn main() {
    println!("Hello, world!");
}

编译和运行示例程序

要编译和运行 examples 目录下的示例程序,可以使用 cargo run --example 命令。下面是一些常用的命令:

列出所有示例

cargo run --example

运行特定示例

运行 hello_world 示例:

cargo run --example hello_world
cargo test --example hello_world
cargo test --examples  # run all of examples

cargo-workspaces

setup project


cargo

cargo install cargo add

details

cargo install rand and cargo add rand serve different purposes in the Rust ecosystem. Here's a detailed comparison of the two commands:

cargo install rand

  • Purpose: Installs a binary crate globally.
  • Usage: cargo install <crate-name>
  • Example: cargo install rand
  • Effect:
    • Downloads and compiles the rand crate (or any specified crate) as a binary and installs it in a location where it can be run globally (usually ~/.cargo/bin).
    • The rand crate doesn't provide binaries, so running cargo install rand would result in an error:
      error: specified package `rand` has no binaries
      
    • Useful for installing command-line tools written in Rust, such as ripgrep, fd, or cargo-edit.

cargo add rand

  • Purpose: Adds a crate as a dependency to your project's Cargo.toml file.
  • Usage: cargo add <crate-name>
  • Example: cargo add rand
  • Effect:
    • Modifies the Cargo.toml file of your Rust project to include rand as a dependency.
    • Automatically resolves the latest version and adds the corresponding line in the [dependencies] section:
      [dependencies]
      rand = "0.8"
      
    • cargo add is a command provided by the cargo-edit crate, which needs to be installed first using cargo install cargo-edit.

Key Differences

  • Installation Scope:

    • cargo install: Installs binaries globally.
    • cargo add: Adds libraries as dependencies to your local project.
  • Use Case:

    • cargo install: Used for installing Rust-based tools and binaries.
    • cargo add: Used for managing project dependencies.
  • Output:

    • cargo install: A binary available globally.
    • cargo add: An updated Cargo.toml file with the new dependency.

Example Usage

  1. Installing cargo-edit to use cargo add:

    cargo install cargo-edit
    
  2. Adding rand as a dependency:

    cargo add rand
    

This will update your Cargo.toml file to include the rand crate as a dependency, allowing you to use it in your Rust project's code.

Summary

  • Use cargo install to install Rust command-line tools and binaries globally.
  • Use cargo add to add libraries as dependencies to your Rust project.

Last Updated:
Contributors: rosendo
Prev
模式匹配(pattern matching)
Next
result & option