标签 Rust 下的文章

Gopher的Rust第一课:第一个Rust程序

本文永久链接 – https://tonybai.com/2024/05/27/gopher-rust-first-lesson-first-rust-program

经过上一章的学习,我想现在你已经成功安装好一个Rust开发环境了,是时候撸起袖子开始写Rust代码了!

程序员这个历史并不算悠久的行当,却有着一个历史悠久的传统,那就是每种编程语言都将一个名为“hello, world”的示例作为这门语言学习的第一个例子,这个传统始于20世纪70年代那本大名鼎鼎的由布莱恩·科尼根(Brian W. Kernighan)与C语言之父丹尼斯·里奇(Dennis M. Ritchie)合著的《C程序设计语言》。

在这一章中,我们也将遵从传统,从编写和运行一个可以打印出“hello, world”的Rust示例程序开始我们正式的Rust编码之旅。我希望通过这个示例程序你能够对Rust程序结构有一个直观且清晰的认识。

3.1 Hello, World

“Hello, World”是一门编程语言的最简单示例的表达形式。在Go中,我们可以像下面这样编写Go版本的Hello, World程序:

package main

func main() {
    println("Hello, World!")
}

为了简单,我们甚至没有使用fmt包的Printf系列函数(这样就可以减少一行导入包的语句),而是用了内置函数println来完成将“Hello, World”输出到控制台(更准确的说是标准错误(stderr))的任务。

Rust版本的Hello, World可以比Go还要简洁,我们在一个目录下(比如rust-guide-for-gopher/helloworld/rustc)创建一个hello_world.rs的文件。哦,没错!rust的源码文件都是以.rs作为源文件扩展名的。并且对于多个单词构成的文件名,rust的惯例是采用全小写单词+下划线连接的方式命名。这个hello_world.rs文件的内容如下:

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

相比于Go在每个源文件中都要使用package指定该文件归属的包名,Rust无需这样的一行。和Go一样,这里的main是函数,所有可执行的Rust程序都必须有一个main函数,它是Rust程序的入口函数。和Go使用func函数声明函数不同,Rust声明函数的关键字为fn。在这个main函数中,我们调用println!将“Hello, World!”输出到控制台上。

不过,和Go内置的println函数不同的是,这里的println!并非是一个函数,而是一个Rust宏(macro)

如果你只是学过Go,而没有学过C/C++语言,你甚至都不会知道宏(macro)是什么。在Rust中,宏是一种用于代码生成和转换的元编程工具。宏允许你在编译时根据一定的模式或规则来扩展代码。Rust宏分为声明宏(Declarative Macros)和过程宏(Procedural Macros)。println!就属于声明宏,它由macro_rules! 宏定义,我们在Rust标准库的源码中可以看到其定义:

// $(rustc --print sysroot)/lib/rustlib/src/rust/library/std/src/macros.rs

#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")]
#[allow_internal_unstable(print_internals, format_args_nl)]
macro_rules! println {
    () => {
        $crate::print!("\n")
    };
    ($($arg:tt)*) => {{
        $crate::io::_print($crate::format_args_nl!($($arg)*));
    }};
}

在Rust源码编译过程中,声明宏是在最开始的预处理阶段进行扩展的,我们也可以通过nightly版的rustc命令来查看println!宏展开后的结果(-Z选项只能在nightly版本中使用):

$rustc +nightly-2022-07-14-x86_64-apple-darwin  -Zunpretty=expanded  hello_world.rs
#![feature(prelude_import)]
#![no_std]
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
extern crate std;
fn main() {
    {
        ::std::io::_print(::core::fmt::Arguments::new_v1(&["Hello, World!\n"],
                &[]));
    };
}

我们看到:println!宏被替换为一个标准库下的函数(_print)的调用。btw,到这里,你可能和我一样,看不懂println!展开后的代码,没关系,我们后续会逐步学习并掌握这些语法的。此外,宏是Rust的高级特性,这里也不展开说了。

另外一个和Go在语法上有所不同的是,Rust在每行语句后面都要显式使用分号,对于Gopher而言,这个很容易遗忘。

接下来,我们来编译和运行一下这个Rust版的Hello,World!,编译运行Rust代码的最简单方法就是通过rustc编译器将rust源码文件编译为可执行程序:

$rustc hello_world.rs

$ls
hello_world*        hello_world.rs

我们看到,示例通过调用rustc将hello_world.rs编译为了hello_world可执行文件。

运行rustc编译后的可执行文件将得到下面输出结果:

$./hello_world
Hello, World!

我们看到”Hello, World!”被打印到控制台。

如果觉得默认编译出的hello_world文件名字较长,我们也可以像go build -o那样指定rustc编译后得到的目标可执行文件的名字,下面的命令通过-o选项将编译后的程序命名为hello:

$rustc -o hello hello_world.rs

rustc编译出来的二进制文件size并不大,仅有400多KB(而Go默认构建的Hello, World!有1.3MB,在我的macOS上):

$ls -lh
total 856
-rwxr-xr-x  1 tonybai  staff   423K  4 20 17:56 hello_world*

我们还可以通过去掉symbols的方式继续让其“瘦身”到不到300KB(通过go build -ldflags=”-s -w” helloworld.go去除符号表和调试信息的Go二进制程序还有近900K的大小):

$rustc -C strip=symbols hello_world.rs
$ll -h
total 608
-rwxr-xr-x  1 tonybai  staff   297K  4 20 17:57 hello_world*

上面的”Hello, World”程序虽然足够简单,也能够运行,但对于初学者而言,它有两个“不足”:一来这个例子的确“太简单”,简单到无法充分展示单个Rust源码文件的结构;二来这个示例只使用了一个单个源文件,与实际开发中那种由多个文件组成的Rust实用工程有差别,同样无法帮助我们理解实用性的Rust工程的结构。

为了更好地理解Rust工程与单个源文件的构成,我们将编写一个稍微复杂一点的版本,它将使用Rust的构建管理工具cargo建立,并使用Rust标准库中的std::io模块进行输入/输出操作。

3.2 cargo版本的Hello, World

在实际开发中,Rust程序通常由多个源文件组成,并使用Cargo作为构建系统和包管理器。Cargo可以帮助我们管理项目的源代码、依赖库、构建任务等。下面我们就来创建一个使用Cargo的”Hello, World”。

3.2.1 使用Cargo创建Hello,World

我们在一个目录下(比如:rust-guide-for-gopher/helloworld/cargo)执行下面命令来创建hello_world:

$cargo new hello_world
    Created binary (application) `hello_world` package

cargo默认创建了一个binary(application)类型的rust package,我们来看看初始情况下这个rust package下都有哪些内容:

$tree hello_world
hello_world
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files

其中,Cargo.toml是Rust包的清单(manifest)文件。它包含有关包及其依赖项的元数据。以下是上面Cargo.toml文件的全部内容:

// Cargo.toml
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

其中package下面的字段含义如下:

  • name: 包的名称;
  • version: 包的版本,遵循语义化版本控制规则;
  • edition: 包使用的Rust版本(edition)。在这里,它被设置为目前的最新edition:2021版。edition提供了一种向后兼容的方式来演化和改进Rust。每个edition都是向后兼容的,这意味着旧edition下编写的Rust代码可以继续在新edition版本的Rust下编译和运行,而无需进行修改。这样,开发者可以按照自己的节奏选择是否迁移到新的edition。

dependencies下面则是会记录该package对第三方依赖的情况,这个示例中并无三方依赖,因此这里为空。

我们的代码放在了src目录下,这也是rust包的标准布局。为了更好地理解Rust程序的构成,我们将编写一个稍微复杂一点的Hello, World!版本,它使用Rust标准库中的std::io模块进行输入/输出操作:

// rust-guide-for-gopher/helloworld/cargo/hello_world/src/main.rs
use std::io;
use std::io::Write;

fn main() {
    let mut output = io::stdout();
    output.write(b"Hello, World!").unwrap();
    output.flush().unwrap();
}

这个Rust的”Hello, World”程序展示了一个典型的Rust源文件结构,包括导入语句、主函数定义以及一系列的方法调用。它演示了如何使用标准库的io模块来向标准输出流打印”Hello, World!”。下面是对其程序结构的简单总结:

  1. 导入语句

源文件在最开始处使用use std::io; 和use std::io::Write;这两行导入了标准库中的io模块及其Write trait。这样程序就可以在后面的代码中直接使用io和Write,而无需完整地写出它们的命名空间。这里我们先不用关心trait是什么,你大可将其理解为和Go interface差不多的语法元素就行了。

  1. 主函数

main定义了程序的入口点。Rust 程序从main函数开始执行。

  1. 可变变量

let mut output = io::stdout(); 这行代码创建了一个可变变量output,它绑定到了一个标准输出流(stdout)。mut关键字表示该变量是可变的,可以在后续代码中修改它的值。关于变量以及绑定,我们在后面有专门的章节说明。这里要注意的是,和Go变量不同的是,Rust中的变量默认是不可变的,只有显式用mut声明的变量才是可变的。

  1. 方法调用

output.write(b”Hello, World!”).unwrap(); 调用了output的write方法,传递了一个字节串作为参数。该方法用于将字节写入输出流。unwrap方法用于处理方法调用可能产生的错误,它在这里表示“我相信这个方法调用会成功,如果不成功,就让程序 panic”。同理,output.flush().unwrap()也是这样的。关于错误以及异常处理的话题,我们会在后面进行专题性学习。

理解了源码后,我们来编译和运行一下这个程序,这次我们不再使用rustc,而是用cargo来实现。

3.2.2 使用Cargo构建Hello, World

要构建上面的示例程序,我们只需在项目根目录下运行下面命令:

$cargo build
   Compiling hello_world v0.1.0 (/Users/tonybai/Go/src/github.com/bigwhite/experiments/rust-guide-for-gopher/helloworld/cargo/hello_world)
    Finished dev [unoptimized + debuginfo] target(s) in 1.23s

构建成功后,我们再来查看一下当前项目下的结构变化:

$tree -F
.
├── Cargo.lock
├── Cargo.toml
├── src/
│   └── main.rs
└── target/
    ├── CACHEDIR.TAG
    └── debug/
        ├── build/
        ├── deps/
        │   ├── hello_world-07284f5d84374479*
        │   ├── hello_world-07284f5d84374479.1atc14vk0u28taij.rcgu.o
        │   ├── hello_world-07284f5d84374479.1bu89c2i9mazzqif.rcgu.o
        │   ├── hello_world-07284f5d84374479.26e3nxhmk9lhy9zy.rcgu.o
        │   ├── hello_world-07284f5d84374479.29l81xyv0i4g8s88.rcgu.o
        │   ├── hello_world-07284f5d84374479.41i7ln85cwseljfw.rcgu.o
        │   ├── hello_world-07284f5d84374479.4iz3ubiqrvegnjdp.rcgu.o
        │   ├── hello_world-07284f5d84374479.53vu8cjirf8g6rnw.rcgu.o
        │   ├── hello_world-07284f5d84374479.5f6ye0ayl23rccqv.rcgu.o
        │   └── hello_world-07284f5d84374479.d
        ├── examples/
        ├── hello_world*
        ├── hello_world.d
        └── incremental/
            └── hello_world-16yuztatbr0vh/
                ├── s-gvfwmugno5-1gy801r-1i2g78r4nmg489ix0nuktmqgb/
                │   ├── 1atc14vk0u28taij.o
                │   ├── 1bu89c2i9mazzqif.o
                │   ├── 26e3nxhmk9lhy9zy.o
                │   ├── 29l81xyv0i4g8s88.o
                │   ├── 41i7ln85cwseljfw.o
                │   ├── 4iz3ubiqrvegnjdp.o
                │   ├── 53vu8cjirf8g6rnw.o
                │   ├── 5f6ye0ayl23rccqv.o
                │   ├── dep-graph.bin
                │   ├── query-cache.bin
                │   └── work-products.bin
                └── s-gvfwmugno5-1gy801r.lock*

9 directories, 28 files

我们看到cargo build执行后,项目下多出了好多目录和文件。这些目录和文件都是做什么的呢?我们挑选主要的来看一下。

  • Cargo.lock文件

Cargo的锁定文件,用于记录每个依赖项的确切版本号,以保证构建的可重复性。

这个示例中由于没有使用第三方依赖,这个Cargo.lock文件中的内容不具典型性:

# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "hello_world"
version = "0.1.0"

另外Cargo.lock文件完全由cargo自动管理,开发人员不需要也不应该对其进行手动修改。

  • target目录

存放构建输出的目录,用于存储编译后的目标文件和可执行文件。

  • target/CACHEDIR.TAG

用于标记target目录为一个缓存目录的文件。它的内容如下:

$cat CACHEDIR.TAG
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by cargo.
# For information about cache directory tags see https://bford.info/cachedir/

这是一个符合Cache Directory Tagging Specification的Tag文件。

  • target/debug

调试模式下的构建输出目录,存储生成的可执行文件和相关文件。

  • target/debug/incremental

增量编译的目录,用于存储增量编译过程中的临时文件和缓存。

Rust编译过程缓慢,这个对比Go简直就是地下天上。在日常开发中,基于增量编译的文件进行增量构建可以大幅缩短编译时间。

  • target/debug/build

编译过程中生成的临时构建文件的目录。

  • target/debug/deps

存储编译生成的目标文件(.o 文件)和相关的依赖项。

  • target/debug/hello_world

调试模式下生成的可执行文件。

  • target/debug/hello_world.d

与hello_world相关的依赖关系信息的文件。

执行debug目录下的hello_world将得到如下输出:

$./target/debug/hello_world
Hello, World!

在Go中我们可以使用go run来直接编译和运行Go源码文件,cargo也提供了该功能,我们在项目根目录下运行cargo run也可以编译和执行hello_world:

$cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/hello_world`
Hello, World!

无论是cargo run还是cargo build,默认构建的都是debug版本的可执行程序,程序中包含大量符号信息和调试信息,并且其优化级别也不是很高。发布到生产环境的程序应该是release模式下的,通过–release参数,我们可以构建release版本的可执行程序:

$cargo build --release
   Compiling hello_world v0.1.0 (/Users/tonybai/Go/src/github.com/bigwhite/experiments/rust-guide-for-gopher/helloworld/cargo/hello_world)
    Finished release [optimized] target(s) in 1.06s

构建后,target目录下会多出一个release目录,其下面的内容如下:

$tree -F target/release
target/release
├── build/
├── deps/
│   ├── hello_world-c41defdc625f9244*
│   └── hello_world-c41defdc625f9244.d
├── examples/
├── hello_world*
├── hello_world.d
└── incremental/

4 directories, 4 files

相对于debug版本,release版本由于实时了大量优化,通常其构建时间会比debug版本要长。但构建出的release版本的size则要小很多。

无论是debug,还是release版,target下面都生成了许多中间文件,如果要清理文件并重头构建,我们可以使用cargo clean命令将target彻底清除:

$cargo clean
     Removed 40 files, 2.1MiB total

当然cargo clean也支持一些命令行参数,可以选择清除哪些文件。

3.2.3 使用Cargo创建library类包

通过上面的例子,我们知道cargo new默认创建的binary类型的rust package,如果我们要创建library类型的rust package,我们需要向cargo new传递–lib选项。下面的命令创建一个名为foo的library类型的rust package:

$cargo new --lib foo
     Created library `foo` package

我们看一下foo package下的目录结构:

$tree -F foo
foo
├── Cargo.toml
└── src/
    └── lib.rs

1 directory, 2 files

和binary类不同的是,src目录下不再是main.rs,而是lib.rs,它是library类package的入口:

//rust-guide-for-gopher/helloworld/cargo/foo/lib.rs

pub fn add(left: usize, right: usize) -> usize {
    left + right
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }
}

lib.rs中只是一个library类package的入口模板,开发人员需要根据自己的需要对其进行调整。关于lib.rs中的内容,我们将在下一章讲解Rust代码组织时做细致说明,这里就不展开说了。

对于library类Rust package,我们同样可以通过cargo build和cargo build –release构建,下面是执行构建后目录文件情况:

$tree
.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── lib.rs
└── target
    ├── CACHEDIR.TAG
    ├── debug
    │   ├── build
    │   ├── deps
    │   │   ├── foo-24c6d6228c521501.2k5t0f94hnorqpgh.rcgu.o
    │   │   ├── foo-24c6d6228c521501.d
    │   │   ├── libfoo-24c6d6228c521501.rlib
    │   │   └── libfoo-24c6d6228c521501.rmeta
    │   ├── examples
    │   ├── incremental
    │   │   └── foo-m2biu8poxl6i
    │   │       ├── s-gvg68shtlp-1oqrf4n-irxhgoe7rhwmtvj6jwexcu0h
    │   │       │   ├── 2k5t0f94hnorqpgh.o
    │   │       │   ├── dep-graph.bin
    │   │       │   ├── query-cache.bin
    │   │       │   └── work-products.bin
    │   │       └── s-gvg68shtlp-1oqrf4n.lock
    │   ├── libfoo.d
    │   └── libfoo.rlib
    └── release
        ├── build
        ├── deps
        │   ├── foo-9f2dd76beda509bd.d
        │   ├── libfoo-9f2dd76beda509bd.rlib
        │   └── libfoo-9f2dd76beda509bd.rmeta
        ├── examples
        ├── incremental
        ├── libfoo.d
        └── libfoo.rlib

14 directories, 20 files

我们看到,无论是debug还是release,cargo build构建的结果都是libfoo.rlib。.rlib文件是Rust的静态库文件,通常用于代码的模块化和重用,我们在后续章节讲解中,会详细说明如何使用这些构建出来的静态库。

3.3 小结

本文介绍了如何使用Rust编写”Hello, World”程序,并分别给出了rustc版和cargo版的hello, world程序版本。

在这个过程中,文章还介绍了Rust中的宏概念,并展示了如何使用println!宏来输出文本。

之后,文章聚焦于使用Cargo构建的hello,world程序版本,介绍了cargo的构建、清理、debug和release版本的区别等,最后还提及了如何使用cargo创建library类的Rust package。

cargo贯穿Rust程序的整个生命周期,在后续的每一章中可能都会提及cargo。

本章中涉及的源码可以在这里下载。


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

Gopher的Rust第一课:建立Rust开发环境

本文永久链接 – https://tonybai.com/2024/05/10/gopher-rust-first-lesson-setup-dev-env

经过上一章的对Rust诞生演化的了解以及设计哲学的探讨后,如果你依然决定继续Rust编程学习之旅,那么欢迎你和我一起正式走进Rust学习和实践的课堂。

编程不是“纸上谈兵”,它是一门实践的艺术。编程语言的学习离不开动手实践,因此学习任何一门编程语言的第一步都是要拥有一个这门编程语言的开发环境,这样我们才可以动手编码,理论与实践结合,不仅加速学习效率,还能取得更好的学习效果。

在这一章中我们就先来学习下如何安装和配置Rust开发环境。如果你的机器上还没有Rust开发环境,那么就请跟我一起选择一种适合你的Rust安装方法吧。

第一步,我们先来挑一个合适的Rust版本。

2.1 选择Rust版本

2.1.1 Go与Rust发布版本与节奏的对比

《Go语言第一课专栏》讲解如何建立Go开发环境时,我首先讲解的也是选择Go版本。我们知道Go一年发布两次大版本,分别是每年的2月和8月,并且Go核心团队只对最近的两个大版本提供support。在处于support时间窗口中的时候,Go核心团队会发布一些补丁版本,修正及少量的严重问题或安全漏洞。比如Go 1.22版本是2024年2月份发布的,到2024年4月中旬,Go 1.22的最新补丁版本已经到了Go 1.22.2了。下图展示了Go版本发布的节奏以及support的窗口:

在Go中,我们可以选择最新稳定版(比如图中的Go 1.22.2)和次新稳定版(比如图中的1.21.8),这两个是Go社区选择最多的。此外,也可以选择某个特定的稳定版(因某种特殊原因,被阻塞在该版本上)以及tip版,其中tip版(master分支上的最新commit版本)主要用于体验最新的、尚未发布的功能特性或问题修复,或是contributor多使用tip版。

Rust的版本发布节奏与Go完全不同,因此Rust版本的选择逻辑与Go相比也就有所不同。下图展示了Rust的版本发布方法与节奏:

我们看到:Rust采用“6周一个稳定版”的滚动发布节奏,并且有三类版本:稳定版(stable)、公测版(beta)和nightly版,分别对应的是stable分支、beta分支和master分支。三个版本间是关联紧密的。

以图中的rust 1.77.0的发布为例,rust 1.77.0稳定版本的发布动作是这样的:

  • 基于当前beta分支(其实就是1.77.0 beta)创建新的stable分支,并tag 1.77.0;
  • 基于当前master分支(nightly版本)创建新的beta分支,并在新的beta分支上公测1.78.0版本,为六周后的1.78.0稳定版做准备;
  • 而master分支上继续开发v1.79.0的新特性,并每天发布Nightly版本。

之后,原1.76.0稳定版便会从support窗口删除,1.77.0进入Support窗口。如果新发布的1.77.0有紧急或安全问题需要修复,则通过补丁(patch)版本进行,比如rust 1.77.1、1.77.2等。

Rust这种“稳定一版,公测一版,开发一版”的“三路并发”的滚动开发节奏,显然要比Go的“稳定一版,开发一版”的“两路并发”节奏要快上很多。不过,频繁的更新可能对某些用户来说是一个挑战,需要他们不断学习和适应新的变化。另外,较快的演进速度也可能导致一些不稳定因素,需要开发者更加谨慎地使用新功能特性。

2.1.2 Rust的三类版本

选择Rust版本根据自己的角色和面对的场合来进行:

  • 对于大多数Rust开发者而言,最新的稳定版(stable)是最好和最明智的选择;
  • 也有少部分因为各种特殊原因,可能阻塞在某个特定的稳定版上;
  • Beta版contributor,或是想提前尝鲜下一个稳定版新特性的开发人员,可以临时使用beta版本;
  • Nightly版,主要针对的也是contributor,或是想临时尝鲜最新不稳定功能特性的开发人员。

Rust提供的安装和升级工具rustup可以灵活的在三类版本间切换:

rustup default beta
rustup default nightly
rustup default stable

切换后,rustup会自动同步该类版本到最新版:

$rustup default beta
info: syncing channel updates for 'beta-x86_64-apple-darwin'
info: latest update on 2024-04-11, rust version 1.78.0-beta.6 (27011d5dc 2024-04-09)
... ...

确定了要使用的Rust版本后,我们接下来就来看看究竟如何安装Rust。

2.2 安装Rust

2.2.1 使用rustup安装

和Go尽可以通过安装包或下载预编译二进制包进行首次安装不同,Rust官方提供了统一的Rust安装、管理和升级工具- rustup。 Rust官方在Linux和macOS上提供了“curl | sh”的一键式安装命令:

$curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

我们以Linux下安装rustup为例,看一下执行上面命令的过程和最终结果:

$curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer

Welcome to Rust!

This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.

Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:

  /root/.rustup

This can be modified with the RUSTUP_HOME environment variable.

The Cargo home directory is located at:

  /root/.cargo

This can be modified with the CARGO_HOME environment variable.

The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:

  /root/.cargo/bin

This path will then be added to your PATH environment variable by
modifying the profile files located at:

  /root/.profile
  /root/.bashrc

You can uninstall at any time with rustup self uninstall and
these changes will be reverted.

Current installation options:

   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with standard installation (default - just press enter)
2) Customize installation
3) Cancel installation

> // 敲击回车

info: profile set to 'default'
info: default host triple is x86_64-unknown-linux-gnu
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2024-04-09, rust version 1.77.2 (25ef9e3d8 2024-04-09)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 14.9 MiB /  14.9 MiB (100 %)   3.7 MiB/s in  3s ETA:  0s
info: installing component 'rust-std'
 24.3 MiB /  24.3 MiB (100 %)   8.2 MiB/s in  2s ETA:  0s
info: installing component 'rustc'
 60.3 MiB /  60.3 MiB (100 %)   9.6 MiB/s in  6s ETA:  0s
info: installing component 'rustfmt'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu installed - rustc 1.77.2 (25ef9e3d8 2024-04-09)

Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, you need to source
the corresponding env file under $HOME/.cargo.

This is usually done by running one of the following (note the leading DOT):
. "$HOME/.cargo/env"            # For sh/bash/zsh/ash/dash/pdksh
source "$HOME/.cargo/env.fish"  # For fish

接下来按照提示执行下面命令,使得Rust相关的环境变量生效:

$. "$HOME/.cargo/env"
$which rustup
/root/.cargo/bin/rustup

. “$HOME/.cargo/env”这行代码也被追加到/root/.bashrc文件中,如果新启动一个terminal窗口,这行shell配置也会被执行,即rustup的环境变量也生效。

查看一下安装的rustup的版本:

$rustup -V
rustup 1.27.0 (bbb9276d2 2024-03-08)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.77.2 (25ef9e3d8 2024-04-09)`

同时我们看到:首次安装rustup时,如果选择“standard installation”,rustup会为我们安装一个最新的Rust stable版本,这里是1.77.2,我们可以通过rustup show命令查看已安装的rust工具链:

$rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /root/.rustup

stable-x86_64-unknown-linux-gnu (default)
rustc 1.77.2 (25ef9e3d8 2024-04-09)

除此之外,rustup还在你的系统中都做了啥呢?我们下面来探索一下。

2.2.1.1 安装后的探索

根据rustup在安装过程中的提示,有两个路径是需要重点关注的。

一个就是\$HOME/.cargo,rustup将.cargo/bin加入到了\$PATH变量下,我们来看看.cargo下都有哪些目录和文件:

$tree -F .cargo
.cargo
|-- bin/
|   |-- cargo*
|   |-- cargo-clippy*
|   |-- cargo-fmt*
|   |-- cargo-miri*
|   |-- clippy-driver*
|   |-- rls*
|   |-- rust-analyzer*
|   |-- rustc*
|   |-- rustdoc*
|   |-- rustfmt*
|   |-- rust-gdb*
|   |-- rust-gdbgui*
|   |-- rust-lldb*
|   `-- rustup*
`-- env

.cargo下主要的目录就是bin,这里存放了日常rust开发时在命令行使用的所有cli命令,包括cargo(构建管理工具)、rustc(编译器)、rustdoc、rustfmt以及rustup自身等。

另外一个更值得关注的目录就是\$HOME/.rustup目录,这个目录下的内容较多,我们通过tree命令查看的结果如下:

$tree -F -L 3  .rustup
.rustup
|-- downloads/
|-- settings.toml
|-- tmp/
|-- toolchains/
|   `-- stable-x86_64-unknown-linux-gnu/
|       |-- bin/
|       |-- etc/
|       |-- lib/
|       |-- libexec/
|       `-- share/
`-- update-hashes/
    `-- stable-x86_64-unknown-linux-gnu

settings.toml是一个rustup配置文件,它的内容如下:

$cat .rustup/settings.toml
default_toolchain = "stable-x86_64-unknown-linux-gnu"
profile = "default"
version = "12"

[overrides]

这里的default_toolchain指示了当前默认使用的工具链版本为stable-x86_64-unknown-linux-gnu。这个版本也是一个target,Rust支持的不同平台上的target以及含义如下图:

.rustup下的另外一个值得注意的目录是toolchains,它下面存放了安装到本地的所有版本的toolchain,上面由于只安装了stable的最新版本,因此当前toolchains下只有一个stable-x86_64-unknown-linux-gnu目录。

值得注意的是.rustup中存储了rust工具链的所有内容,因此它的空间占用也着实可观:

$ du -sh .rustup
1.2G    .rustup

现在我们来切换默认版本到beta:

$rustup default beta
info: syncing channel updates for 'beta-x86_64-unknown-linux-gnu'
info: latest update on 2024-04-11, rust version 1.78.0-beta.6 (27011d5dc 2024-04-09)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 15.1 MiB /  15.1 MiB (100 %)   3.4 MiB/s in  3s ETA:  0s
info: installing component 'rust-std'
 24.2 MiB /  24.2 MiB (100 %)   9.3 MiB/s in  2s ETA:  0s
info: installing component 'rustc'
 63.5 MiB /  63.5 MiB (100 %)   9.6 MiB/s in  6s ETA:  0s
info: installing component 'rustfmt'
info: default toolchain set to 'beta-x86_64-unknown-linux-gnu'

  beta-x86_64-unknown-linux-gnu installed - rustc 1.78.0-beta.6 (27011d5dc 2024-04-09)

我们看到rustup会自动下载安装最新的beta版本,安装后,我们再执行rustc -V来查看当前版本,我们发现结果已经变为了下面这样:

$ rustc -V
rustc 1.78.0-beta.6 (27011d5dc 2024-04-09)

这里值得注意的是,虽然我们执行的rustc是.cargo/bin/rustc,但.cargo/bin/rustc有些类似于一个指针,真正执行的是其“指向”的某个工具链版本的rustc,我们可以使用rustup which rustc来查看究竟执行的是哪个rustc:

$ rustup which rustc
/root/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/bin/rustc

此时,.rustup目录下面发生了怎样的变化呢?我们来看看:

$ tree -F -L 3  .rustup
.rustup
|-- downloads/
|-- settings.toml
|-- tmp/
|-- toolchains/
|   |-- beta-x86_64-unknown-linux-gnu/
|   |   |-- bin/
|   |   |-- etc/
|   |   |-- lib/
|   |   |-- libexec/
|   |   `-- share/
|   `-- stable-x86_64-unknown-linux-gnu/
|       |-- bin/
|       |-- etc/
|       |-- lib/
|       |-- libexec/
|       `-- share/
`-- update-hashes/
    |-- beta-x86_64-unknown-linux-gnu
    `-- stable-x86_64-unknown-linux-gnu

我们看到toolchains下面多了一个beta-x86_64-unknown-linux-gnu目录,存放的就是刚刚安装的beta最新版本工具链。

现在我们在用rustup show命令查看已安装的rust工具链,其结果如下:

$rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /root/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu
beta-x86_64-unknown-linux-gnu (default)

active toolchain
----------------

beta-x86_64-unknown-linux-gnu (default)
rustc 1.78.0-beta.6 (27011d5dc 2024-04-09)

现在,我们切换回stable版本,由于stable版本之前已经安装完毕,也就无需下载和安装过程了:

$rustup default stable
info: using existing install for 'stable-x86_64-unknown-linux-gnu'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.77.2 (25ef9e3d8 2024-04-09)

2.2.1.2 安装和使用特定版本rust工具链

我们还可以使用rustup安装特定版本的rust工具链,比如通过下面的命令,我们安装stable版本的1.66.0:

$ rustup install 1.66.0
info: syncing channel updates for '1.66.0-x86_64-unknown-linux-gnu'
info: latest update on 2022-12-15, rust version 1.66.0 (69f9c33d7 2022-12-12)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 19.0 MiB /  19.0 MiB (100 %)   4.4 MiB/s in  3s ETA:  0s
info: installing component 'rust-std'
 29.7 MiB /  29.7 MiB (100 %)   8.1 MiB/s in  3s ETA:  0s
info: installing component 'rustc'
 68.0 MiB /  68.0 MiB (100 %)  10.2 MiB/s in  6s ETA:  0s
info: installing component 'rustfmt'

  1.66.0-x86_64-unknown-linux-gnu installed - rustc 1.66.0 (69f9c33d7 2022-12-12)

info: checking for self-update

安装ok后,我们再来看看.rustup目录下的变化:

$tree -F -L 3  .rustup
.rustup
|-- downloads/
|-- settings.toml
|-- tmp/
|-- toolchains/
|   |-- 1.66.0-x86_64-unknown-linux-gnu/
|   |   |-- bin/
|   |   |-- etc/
|   |   |-- lib/
|   |   |-- libexec/
|   |   `-- share/
|   |-- beta-x86_64-unknown-linux-gnu/
|   |   |-- bin/
|   |   |-- etc/
|   |   |-- lib/
|   |   |-- libexec/
|   |   `-- share/
|   `-- stable-x86_64-unknown-linux-gnu/
|       |-- bin/
|       |-- etc/
|       |-- lib/
|       |-- libexec/
|       `-- share/
`-- update-hashes/
    |-- 1.66.0-x86_64-unknown-linux-gnu
    |-- beta-x86_64-unknown-linux-gnu
    `-- stable-x86_64-unknown-linux-gnu

我们看到toolchains下面多了一个1.66.0-x86_64-unknown-linux-gnu,那我们如何使用新下载的1.66.0 stable版本呢?有几种方法,下面逐一介绍一下。

我们可以使用rust工具链的“plus语法”在命令行上指定要使用的工具链,这个语法对cargo、rustc等工具链中的命令行程序都适用:

$ rustc +1.66.0 -V
rustc 1.66.0 (69f9c33d7 2022-12-12)
$ rustc +1.65.0 -V
error: toolchain '1.65.0-x86_64-unknown-linux-gnu' is not installed

$ cargo +1.66.0 -V
cargo 1.66.0 (d65d197ad 2022-11-15)
$ cargo +1.65.0 -V
error: toolchain '1.65.0-x86_64-unknown-linux-gnu' is not installed

注:cargo是Rust语言的官方构建系统和包管理器,它提供了一组命令行工具,可以自动化构建、测试和发布Rust项目。它还支持自动解析和下载依赖项,使得管理项目的依赖关系变得简单和可靠。Cargo是Rust生态系统中重要的工具之一,为开发者提供了高效和方便的开发体验。在后面的章节中我会详细介绍cargo。

对于要使用特定版本进行构建的rust项目,我们可以通过rustup override来指定版本号。下面就是一个这样的例子:

$cargo new hellorust
     Created binary (application) `hellorust` package
$cd hellorust/
$rustup override set 1.66.0
info: override toolchain for '/root/test/rust/hellorust' set to '1.66.0-x86_64-unknown-linux-gnu'

我们用cargo创建了一个新的hellorust项目,在hellorust项目下,我们执行rustup override来指定该项目使用1.66.0版本进行构建。

之后,我们分别在该项目目录下以及其他目录下执行rustc,我们看到输出结果如下:

~/test/rust/hellorust$ rustc -V
rustc 1.66.0 (69f9c33d7 2022-12-12)
$ cd ..
~/test/rust$ rustc -V
rustc 1.77.2 (25ef9e3d8 2024-04-09)

rustc override的原理其实是在$HOME/.rustup/settings.toml文件中添加了一些内容:

$cat .rustup/settings.toml
default_toolchain = "stable-x86_64-unknown-linux-gnu"
profile = "default"
version = "12"

[overrides]
"/root/test/rust/hellorust" = "1.66.0-x86_64-unknown-linux-gnu"

我们看到在overrides下新增了一条规则,指定了hellorust项目需要使用1.66.0-x86_64-unknown-linux-gnu这个工具链。

不过这种与本地路径紧耦合的配置方案并不是适合大范围协作,无法提交到git仓库中分享给其他人。

Rust还提供了另外一种override toolchain版本的方法,我们可以在hellorust项目的根目录下放置一个名为rust-toolchain.toml的文件,其内容如下:

// rust-toolchain.toml

[toolchain]
channel = "1.66.0"

我们先执行rustup override unset将上面设置的override规则取消掉:

$rustup override unset
info: override toolchain for '/root/test/rust/hellorust' removed

然后toolchain.toml就会生效了:

// 在hellorust路径下
$rustc -V
rustc 1.66.0 (69f9c33d7 2022-12-12)

显然,这里涉及到了override的优先级顺序问题。Rust规定版本override的优先级顺序由高到低依次是:

  1. plus语法:“rustc +1.66.0 -V”
  2. RUSTUP_TOOLCHAIN环境变量 (default: none)
  3. rustup override命令
  4. rust-toolchain.toml
  5. 默认toolchain

2.2.1.3 在Windows上安装Rust

上述通过“curl|ssh”安装rustup,并通过rustup安装Rust工具链的方法是在Linux和macOS上安装Rust的主流方法,但在习惯于图形化安装的Windows上,略有变通。在Windows上,我们可以下载和安装一个名为rustup-init.exe的程序,它等价于其他os上的rustup,但可以交互式的引导用户安装。

由于手旁没有Windows环境,具体的安装过程这里就不详细说明了。

2.2.2 离线安装包安装

和Go一样,Rust也提供了离线安装包的安装方式,在离线安装包下载页面可以找到各个平台的多种文件格式(目前包括.tar.xz、.msi和.pkg)的离线安装包。

习惯在Windows上开发Rust程序的开发者可以直接下载和使用.msi来安装Rust开发环境。

2.3 更新和卸载Rust

使用rustup来更新和卸载Rust非常简单方便。

以更新stable版本为例,通过下面命令,我们就可以将本地的stable版本更新到最新stable版本。以我的macOS为例,我通过rustup将stable版本更新为最新的Rust 1.77.2:

$rustup update stable
info: syncing channel updates for 'stable-x86_64-apple-darwin'
info: latest update on 2024-04-09, rust version 1.77.2 (25ef9e3d8 2024-04-09)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
 14.9 MiB /  14.9 MiB (100 %)   9.3 MiB/s in  1s ETA:  0s
info: downloading component 'rust-std'
 25.4 MiB /  25.4 MiB (100 %) 764.8 KiB/s in 12s ETA:  0s
info: downloading component 'rustc'
 54.9 MiB /  54.9 MiB (100 %)   8.6 MiB/s in  7s ETA:  0s
info: downloading component 'rustfmt'
  1.8 MiB /   1.8 MiB (100 %) 564.9 KiB/s in  3s ETA:  0s
info: removing previous version of component 'cargo'
info: removing previous version of component 'clippy'
info: removing previous version of component 'rust-docs'
info: removing previous version of component 'rust-std'
info: removing previous version of component 'rustc'
info: removing previous version of component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 14.9 MiB /  14.9 MiB (100 %)   4.2 MiB/s in  3s ETA:  0s
info: installing component 'rust-std'
 25.4 MiB /  25.4 MiB (100 %)  13.8 MiB/s in  2s ETA:  0s
info: installing component 'rustc'
 54.9 MiB /  54.9 MiB (100 %)  13.9 MiB/s in  4s ETA:  0s
info: installing component 'rustfmt'

  stable-x86_64-apple-darwin updated - rustc 1.77.2 (25ef9e3d8 2024-04-09) (from rustc 1.75.0 (82e1608df 2023-12-21))
... ...

通过更新的日志,我们看到rust的相关工具组件(比如cargo、rustfmt等)也得到了一并的更新。

Rust通过rustup提供了卸载Rust环境的命令:

$rustup self uninstall

Thanks for hacking in Rust!

This will uninstall all Rust toolchains and data, and remove
$HOME/.cargo/bin from your PATH environment variable.

Continue? (y/N) _

我们看到:rustup会在控制台上与你进行一个确认继续的交互,确认你真的要卸载。如果你输入y并按Enter键继续,那么rustup会移除所有与Rust相关的文件,包括工具链、库、环境变量等。

如果你需要保留一些Rust版本,可以先运行rustup toolchain list,查看已安装的版本。然后用rustup toolchain uninstall命令单独卸载不需要的版本:

$rustup toolchain uninstall 1.64-x86_64-apple-darwin
info: uninstalling toolchain '1.64-x86_64-apple-darwin'
info: toolchain '1.64-x86_64-apple-darwin' uninstalled

2.4 配置Rust

《Go语言第一课专栏》讲解安装Go之后的配置时,我们主要提到了国内开发者要配置一个合适的GOPROXY。而Rust的各个站点都在合规访问范围内,我们安装Rust后无需做任何配置即可敞开使用Rust。

不过也有开发者觉得通过Rust官方下载crate慢,希望更换国内源,这种换源主要涉及的是cargo这个工具,我们后续学习Cargo时再来说明如何换源以及换哪个稳定的国内源。

2.5 在线体验Rust

Go提供了在线的Go playground可供尚未在本地安装Go环境的开发者体验Go语法,Go playground提供了三个版本:最新稳定版、次新稳定版以及tip版本,并且可以将代码通过短连接分享给其他开发者,十分方便。

这方面Rust也不逞多让,提供了功能足够丰富的Rust Playground

在这里,我们可以选择Rust的版本:stable、beta还是nightly;可以选择编译模式,是debug还是release;可以选择Rust edition;可以选择执行一些工具,比如rustfmt;可以选择执行的命令:Run、Build、Test、MIR等。

不过,Rust、Go的playground毕竟只是用于在线体验的站点,他们具有共同的一些局限,比如:不支持第三方依赖,无法做复杂的多源文件项目的体验。

2.6 编辑器与IDE

对于开发人员来说,一门语言的开发环境不仅包含语言官方提供的编译器以及其他工具链,代码编辑器或IDE也是必不可少的。接下来,我们就来简单说说使用什么编辑器或IDE来开发Rust代码。

2023年Rust官方年度的用户调查显示,在编辑器/IDE使用排名中VSCode和VIM位列前二:

Jetbrain推出的商业版RustRover位居第三,正在迎头赶上,但由于是商业版,这里就不详细介绍了。下面我们分别介绍一下如何使用VSCode和VIM来开发Rust代码,都需要安装哪些插件。

2.6.1 使用VSCode开发Rust

使用上面介绍的rustup在本地安装Rust环境后,rust的相关工具(cargo、rustc、rustfmt、rust-analyzer等)就都已经就绪!使用VSCode开发Rust只需再安装一个扩展插件即可,它就是由Rust官方维护的rust-analyzer

该插件实现了Rust语言的Language Server Protocol,可以在开发者编写Rust代码时,提供代码补全、转到定义/实现/类型定义、查找所有引用、工作区符号搜索、符号重命名、悬停时的类型和文档、类型和参数名称的嵌入提示、语义语法高亮等功能。可以说,有了Rust-analyzer的帮助,开发者可以自由在Rust代码中徜徉了。

更详细的VSCode支持Rust开发的文档,可以参考Rust in Visual Studio Code

2.6.2 使用VIM开发Rust

和VSCode仅需安装一个扩展插件相比,VIM的配置就相对复杂一些了。目前Rust+VIM的主流方案是rust.vim + coc.nvim + coc-rust-analyzer

我们以安装了vim-plug插件管理器的VIM为例,下面是VIM的插件关系以及插件与Rust工具链的交互图:

首先,通过vim-plug安装coc.nvim和rust.vim,我们需要在~/.vimrc中添加下面代码:

call plug#begin()
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'rust-lang/rust.vim' "for rust
call plug#end()

然后在vim中执行:PlugInstall安装coc.nvim和rust.vim。

rust.vim是Rust团队官方维护的vim插件,用于提供Rust文件检测、语法高亮显示、代码格式化等,它需要Vim 8或更高版本才能实现完整功能。

coc.nvim则是一个强大的Neovim (Vim的衍生版本)插件,主要用于提供代码补全、语法检查、代码导航等功能,支持多种编程语言。它基于微软的 Language Server Protocol (LSP),可以与各种语言服务器集成,从而为不同语言提供智能化的开发体验。

安装coc.nvim成功后,我们再在VIM中使用:CocInstall coc-rust-analyzer安装coc.nvim的插件:coc-rust-analyzer,通过该插件可以实现与LSP实现rust-analyzer的交互,从而实现代码补全、转到定义/实现/类型定义、查找所有引用等功能。

此外,我们还需要配置一下coc.nvim,配置文件在~/.vim/coc-settings.json中:

{
    "languageserver" : {
            "rust": {
              "command": "rust-analyzer",
              "filetypes": ["rust"],
              "rootPatterns": ["Cargo.toml"]
            }
  }
}

安装好上述插件并完成配置后,你同样可以使用VIM在Rust代码中徜徉!

2.7 小结

在这一章里,我们学习了如何建立Rust开发环境。

首先我了解到,Rust有stable(稳定版)、beta(公测版)和nightly(每晚版)三种版本渠道,发布节奏是每6周一个新的稳定版,与Go语言有所区别。对于大多数开发者来说,选择最新的稳定版是最明智的选择。

接着,我介绍了在Linux环境下使用rustup这个官方工具安装Rust的方法。rustup提供了一键安装命令,可以方便地安装不同渠道的Rust版本。

安装完成后,rustup在主机的主目录下创建了.cargo和.rustup两个目录。.cargo/bin存放了cargo、rustc等命令行工具,.rustup/toolchains则存放了安装的Rust工具链。

我们还学会了如何使用rustup在不同版本间切换,并演练了如何安装指定版本的Rust。另外,通过rustup的”plus语法”,可以在单个命令中临时使用特定的Rust版本。当然Rust提供了不止一种方法,还有rust-toolchain.toml文件、环境变量等方法,请注意这些方法的优先级顺序。

最后,我们还介绍了如何利用Rust playground在线体验Rust编码,以及Rust编码使用的两种最常使用的IDE和编辑器:VSCode和VIM,针对这两个工具,我分别介绍了Rust开发环境的配置方法。

相信大家通过本章内容,已经可以成功搭建了Rust开发环境了,这为后续的Rust编程学习打下了坚实的基础。


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats