标签 vscode 下的文章

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未来演进:基于共同目标和数据驱动的决策

本文永久链接 – https://tonybai.com/2023/12/10/go-changes

自从Go语言之父Rob Pike从Google退休并隐居澳洲后,Russ Cox便成为了Go语言团队的“带头大哥”,虽然其资历还无法与依旧奋战在一线的另外一位Go语言之父Robert Griesemer相比。如今,Russ Cox对Go语言未来的演化发展是很有“发言权”的,Go module的引入便是Russ Cox的重要决策之一。从Go社区来看,这些年来,以Russ Cox为首的Go团队对Go演进决策总体上是良性的、受欢迎的,比如Go module、Go泛型、Go对wasm的支持等,当然也有一些变化是受到质疑的,比如:Go 1.22版本很可能从试验特性到正式特性的loopvar等

注:我的极客时间《Go语言第一课》专栏中有对Go module和Go泛型的详细讲解,欢迎感兴趣的童鞋订阅阅读。

想必很多Gopher也和我一样,对Go团队就某一proposal的决策方式和依据很好奇 –到底他们是如何决定是否accept这个proposal的?Go语言后续该如何演化?向哪个方向发展演化?

今年9月份举办的GopherCon 2023上,Russ Cox代表Go团队做了名为“Go Changes”的主题演讲

在这个talk中,我们能找到一些答案。近期他重新录制了该演讲视频,并在其个人博客中放出。

本文就是基于这个视频内容进行整理加工后的文字稿,供国内广大gopher参考。


这是我在2023年GopherCon上做的一次演讲的重新录制视频。在这次演讲中,我和大家分享了三部分内容:为什么Go需要随着时间的推移而改变,我们如何应对Go的变化过程,以及为什么选择性遥测(opt-in telemetry)是这个过程中的一个重要且适当的部分。不过,这个演讲不是关于某个特定的Go特性变化,而是关于Go整体的变化过程,特别是我们是如何决定做出哪些改变的。

首先一个明显的问题是,为什么Go需要改变? 为什么我们不能对Go感到满意,然后将其束之高阁呢? 一个显而易见的答案是我们不可能一次就把事情做对,你对比一下上面图片中展示的第一版毛绒Go吉祥物和我们在GopherCon上发放的最终版本,你就能明白我的意思了。

但这里还有一个更深层次的答案:

我的一位前同事在他使用了多年的邮件签名中引用了生物学家兼科幻小说作家杰克·科恩(Jack Cohen)的一句名言。在这句名言中,科恩说:“我们生物学家使用的一个描述‘稳定(stable)’的专业词汇就是“死(dead)”。

所有的生命都在变化,适应新的环境,修复损伤等。编程环境也需要改变。除非我们想要Go死掉,否则它需要适应新的环境,比如新的协议、操作系统和重要用例。我们也需要发现并修复bug — 语言、库和生态系统的问题,这些问题只有随着时间的推移或Go发展到一定阶段和规模才会暴露出来。

Go必须改变,并与时俱进。这次演讲就是关于我们如何决定做出哪些改变

这次演讲分三个部分:

  • 第一部分是关于我们对Go的愿景和期望。
  • 第二部分是关于我们如何利用数据来决定做出哪些改变。
  • 第三部分是关于我们在Go工具链中增加选择性遥测的计划,以便更好地理解Go的使用情况和出现问题的地方。

到演讲结束时,你将了解我们考量和决定Go变化的过程,并了解数据在做出这些决定中的重要性,我希望你能理解为什么选择性遥测是一个很好的额外数据来源,甚至可能愿意在系统推出时就选择加入。

让我们从这个开始:我们希望Go发生什么样的变化?如果我们在这个基本问题上意见不一致,我们也就无法就具体的变化达成共识。

例如,我们是否应该在Go中添加一个Perl语句,让我们可以用Perl编写函数?

我认为我们不应该,但假设你有不同意见。为了解决这个问题,我们需要理解为什么我们持不同意见。

约翰·奥斯特豪特(John Ousterhout)写了一份名为“开放决策制定(Open Decision Making)”的好文档,内容虽然来自他在创业公司的经验,但它几乎完全适用于开源项目。

在这份文档中,他提出的最重要的观点之一是:如果一群聪明人面对同一个问题,并具有相同的信息,如果他们有相同的目标,那么他们很可能得出相同的结论

如果你和我在Go中是否要嵌入Perl这个问题上存在分歧,根本原因肯定是我们对Go目标有不同的理解,所以我们必须建立明确Go的目标。

Go的目标是更好的软件工程,特别是大规模软件工程。Go的独特设计决策几乎全部针对这个目标。我们已经多次阐述过这一点,包括在上述截图中的这两篇文章中。再说一次,Go的目标是更好的软件工程

现在我们来说说Perl。20年前,当我很年轻、甚至有些天真、Go还不存在的时候,我编写并部署了一个完全用Perl编写的大型分布式系统。我热爱Perl所擅长的东西,但它并不是以更好的软件工程为目标。如果我们在这一点上有分歧,那么我可能应该定义一下我所说的软件工程是什么意思。

注:如果要理解Go以更好软件工程为目标,或是Google的软件工程理念,可以阅读一下《Software Engineering at Google》这本佳作。

我喜欢说,当你给编程加入时间和其他程序员时,软件工程就出现了。编程意味着让一个程序工作。你有一个要解决的问题,你编写一些代码,运行它,调试它,得到答案,完成。这就是编程,这已经够难的了。

但是当那段代码不得不日复一日地继续工作时会发生什么,甚至和其他人一起对它进行维护?那么你需要添加测试,以确保你修正后的bug不会在6个月后由你自己或是一个不熟悉这段代码的新团队成员重新引入。这就是为什么Go从第一天开始就内置了对测试的支持,并建立了一种文化,那就是对任何bug的修复或新增代码都要添加测试。

那么随着时间的流逝,当代码必须在Go本身发生改变的情况下继续工作时会发生什么?那么我们需要强调兼容性,这是Go1版本以来一直在做的。事实上,Go 1.21版本发布了许多兼容性改进,我在2022年的GopherCon上对此有过介绍。

随着代码量的增长,如果需要某种全局清理时该怎么办?你需要工具,而不可避免的第一个绊脚石是那些工具需要模仿代码的格式化风格来编辑,以避免出现无关的差异。gofmt的存在是为了支持goimports、gorename、go fix和gopls等工具,以及你自己可能使用我们提供的包编写的自定义工具。

既然提到了软件包,当你使用其他人提供的软件包时,不可避免的第一个绊脚石是多个人会用相同的名字(比如sqlite或yaml)编写软件包。那么我们如何在一个给定的程序中识别究竟使用哪个了呢?为了在一个去中心化的方式无歧义地回答这个问题,Go使用URL作为包导入路径。

随着时间的推移,下一个问题是挑选使用特定软件包的哪个版本,并决定该版本是否与所有其他依赖项兼容。这就是为什么Go提供了modules、workspaces、Go modules mirror镜像和Go module校验和数据库。

接下来的问题是每个人的代码都有bug,包括安全bug。你需要了解关于最重要bug的信息,这样你就知道需要更新到已修复的版本。这就是为什么我们添加了Go漏洞数据库和govulncheck,Julie也在GopherCon上谈到了这一点,当有视频链接时我会在下面添加。

以上是较大的例子,但也有小的例子,比如添加新的协议如HTTP/3,移除对过时平台的支持,以及修复或废弃容易出错的API,以避免大型代码库中的常见错误。

这把我们带到了Go提案过程(Proposal Process),这是我们对是否接受(accept)和拒绝(decline)哪些变更做出决定的方式:

当我们考虑这些决定时,使用数据非常重要,这可以帮助我们达成共识。

简单地说,任何人都可以在Go的GitHub问题跟踪器上提出Go更改提案(Change Proposal)。然后,在该问题上进行讨论,我们试图在参与者之间就是否接受或拒绝该建议达成共识,或者该建议需要做出什么修改才能被接受。

随着时间的推移,我们越来越欣赏约翰·奥斯特豪特在他的观察中提出的第二句话的重要性:如果面对问题的人不仅共同的目标,还有共同的信息,他们很可能会达成共识。

在Go的早期,只有我们几个人做决定。我们根据技术判断和直觉做出决定,这些判断和直觉是基于我们过去的经验。那些经验就是我们使用的信息。由于我们的过去经验有足够的重叠,我们大多数时候能达成共识。大多数小项目都是这种工作方式。

随着决策涉及的人数大大增加,共享经验就会减少。我们需要一个新的共享信息来源。我们发现的最好信息来源是收集实际数据,然后将这些数据作为共享信息来做决策。但是我们从哪里获得这些数据呢?对Go来说,我们有许多潜在的来源,每一个都适合具体的决策类型。在这里,我将向你展示其中的一些。

一个数据来源是与Go用户交谈。我们以各种方式做到这一点:

首先是Go用户调查,我们从2016年开始每年做一次,最近开始一年做两次。调查非常适合了解Go最流行的用途以及人们面临的最常见问题。多年来,最常见的问题是缺乏依赖管理和泛型。我们使用这些信息将开发Go模块和泛型作为优先事项。

另一个数据来源是我们可以在VSCode中使用VSCode Go插件运行的调查。这些调查可以帮助我们了解VSCode Go体验的实效性。

来自用户的最后一个直接数据来源是我们全年进行的研究访谈和用户体验研究。这些研究允许我们从小规模的用户群体中识别模式或获取更多关于特定主题的信息。

调查和访谈通过与用户交谈来收集数据。另一个数据来源是阅读代码:我们可以分析已发布的开源Go module代码。

例如,在添加新的“go vet”检查之前,我们会在开源代码库的一个子集上运行它,然后读取一些随机样本的结果,看检查是否指出了真实的问题,以及它是否有太多的假阳性。

在Go 1.22版本,我们计划添加一个go vet检查,检查对append的调用是否没有append任何内容。这里有检查器标记的两段代码:

顶部的一段代码表明开发人员可能认为append总是复制其输入slice。底部的一段代码可能是正确的,但难于措辞来描述。

这里还有另外两段代码:

在顶部的一段中,或者for循环从未运行,或者它永远不会完成,因为e.Sigs的长度永远不会改变。底部的代码也似乎是一个清晰的bug:代码正在仔细决定将消息追加到哪个列表中,然后它没有将其追加到任何一个列表中。

由于我们对样本代码段进行的所有采样都是可疑的或完全错误的,我们决定添加该检查。在这里,数据比直觉更好。

所有这些方法都是在少量样本上工作。对于典型的代码分析,我喜欢手动检查100个样本,与世界上所有Go代码的量相比,这只是一个微小的比例。最后一份Go开发者调查有不到6000名受访者,而全世界可能有300万Go开发者,样本比例不到1%。

一个很好的问题是为什么这些极小的样本能告诉我们有关更大人群的信息?答案是抽样精度只依赖于样本数量,而不依赖于总体规模。

这乍一看似乎反直觉,但假设我有一个装有100万只Go吉祥物的大箱子,我随机拿出两个。首先我拿到一个蓝色的,然后我拿到一个粉红色的。根据这两个样本,我估计箱子中的吉祥物大约一半是蓝色的,一半是粉红色的。但如果我告诉你箱子里有粉红色、蓝色和灰色的吉祥物,你是否会感到十分惊讶? 不会非常惊讶!如果箱子正好分三分之一粉红色、蓝色和灰色,那么这9对颜色组合中的每一对都同样可能:

得到一个非灰色吉祥物的机会是2/3,得到两个的机会就是2/3的平方,即4/9。没看到灰色的情况出现概率将近一半。这就是为什么我们不会非常惊讶的原因。

现在假设我取出100只,有48只蓝色和52只粉红色。我再次估计箱子大约一半是蓝色,一半是粉红色。现在如果我告诉你箱子里有粉红色、蓝色和灰色的吉祥物,你会有多惊讶?你应该会非常惊讶。

事实上,你完全不应该相信我。如果那是真的,得到100只连续的非灰色吉祥物的机会是2/3的100次方,约等于10的负48次方:

随机出现这种情况的可能性为零。要么我在说谎,要么我没有随机抽取。可能所有的灰色吉祥物都在箱子底部,我没有抽取到足够深的地方。

请注意:这都不依赖于箱子中有多少只Go吉祥物,它只取决于我们取出了多少只。用于特定预测精度的数学更复杂,但具有相同的效果:只有样本数量重要,箱子中的吉祥物数目不重要

一般来说,手工计算这些数学太困难了,所以这里有一个表格,你可以在我的博客上找到:

它说明,如果你提取100个样本并根据这些样本估计百分比,那么90%的时间你的估计将在真实百分比的正负8%之内。99%的时间它们将在13%之内。如果像Go调查中那样有5000个样本,那么90%的时间估计误差在正负1%之内,99%的时间在正负2%之内。超过这个数量,我们实际上不需要更多样本。

有一个注意事项是样本需要是随机的, 或者至少与你正在估计的内容不相关。你不能只从箱子的顶部抽取吉祥物,然后对整个箱子做出断言。

如果你避免了这个错误, 那么当你试图估计一个新的API是否有用或者某个特定的vet check是否值得的时候, 花一个小时左右手动检查100个样本是合理的。如果是一个坏主意, 那将很快显现出来。而如果看起来是一个好主意, 再花几个小时检查更多的样本, 无论是手动检查还是用程序检查,都会大大提高你的估计准确性。与做出错误决策的代价相比,这是一个非常小的成本。

简而言之,采样的魔力在于将许多一次性估计转变为可以手动或用少量数据完成的工作。这就是为什么我们已经看到的所有数据来源都能够相当好地代表整个Go开发者群体的原因。

现在进入演讲的第三部分:Go工具链中的遥测(Telemetry):

遥测也将是Go开发者使用的一个小样本,但它应该是一个有代表性的样本,并且回答不同的问题,而不是调查和代码分析所做的问题。

遥测始终是一个有争议的话题,特别是对于开源项目来说,所以让我从最重要的细节开始说起:上传遥测报告是完全自愿和选择加入的:

除非你运行一个显式命令选择加入数据收集,否则不会上传任何数据。而且,这不是那种上传你的全部活动的详细跟踪的遥测系统。这种遥测也只适用于我们作为Go发行版的一部分分发的命令,比如gopls、go命令和编译器(compiler),它不会涉及你构建的任何程序

在我更详细地描述完这个系统之后,我希望你会发现你会愿意选择加入这个遥测系统。实际上,我们给自己设定的主要设计限制是,即使由其他人运行,我们也愿意选择加入该系统。

在我以2023年11月的录制这个内容时,该系统刚刚开始运行,只有少数人被要求在VSCode Go中选择加入gopls遥测。所以总体来说,你现在还不能选择加入。但希望很快你就可以了。

在我们深入了解细节之前,遥测的动机是它提供了与调查和代码分析不同的信息。它主要提供的两个类别是使用信息(Usage Information)和故障信息(Breakage Information)。调查让我们能够询问关于Go使用的广泛问题,但对于详细的使用信息来说并不好。那将是太多问题,对于调查对象来说,90%的问题要回答”no”是一种浪费时间。

这个幻灯片显示了我们在之前的版本中警告过即将删除的Go功能列表。列表中的最后一项,buildmode=shared,是我们试图移除的功能,但在事先警告后,至少有一个用户提出了异议,我们将其保留了下来。即便如此,buildmode=shared与Go module基本不兼容,所以它的使用可能非常有限。但我们没有数据,所以它仍然存在于代码库中。遥测可以为我们提供基本的使用信息,以便我们可以基于数据而不是猜测做出这些决策。

另一个重要的类别是故障信息:

如果Go工具链明显有问题,我们希望在GitHub上收到错误报告。但是Go工具链也可能以用户注意不到的微妙方式出现问题。一个例子是,在macOS上的Go 1.14到Go 1.19的版本中,标准库包的二进制文件在预先构建时使用了非默认的编译标志,这是一个意外,这使得它们看起来像是过时了,Go命令在运行时会重新编译它们,这意味着如果你的程序导入了net包,你需要安装Xcode中的C编译器来构建程序。我们希望Go能够自行构建纯Go程序,而无需其他工具链。因此,要求安装Xcode是一个bug。但是我们没有注意到这个问题,也没有用户在GitHub上报告它。遇到这个问题的人似乎只是安装了Xcode并继续进行了工作。遥测可以提供基本的性能指标,比如标准库缓存命中率,这样Go工具链的开发人员即使用户没有意识到这个问题,也能注意到这个问题。

另一个例子是编译器的内部崩溃:

Go编译器在程序的第一个错误处不会停止。它会继续进行,尽可能多地查找和报告不同的错误。但是有时,继续分析已知错误的程序会导致意外的panic。我们不希望向用户显示这样的崩溃。相反,编译器会从panic中恢复,并且仅报告已经发现的错误。这样,Go用户可以纠正这些错误,这也可能纠正隐藏的panic。用户的工作不会因为看到编译器崩溃而中断。这对用户来说是好的,但是Go工具链的开发人员仍然希望了解这个崩溃并修复这个错误。遥测可以确保即使用户不知道这个错误,但我们还能了解到这个错误。

为了收集使用情况和故障信息,Go遥测设计记录“计数器和崩溃”:

像go命令、Go编译器或gopls这样的Go工具链程序可以定义命名事件计数器,并在事件发生时递增计数器。事件还可以按堆栈跟踪单独计数。这些计数器在本地的磁盘文件中维护,每次保留一周的时间。在幻灯片上,gopls和其他工具正在将计数器写入每周的文件中。

每周一次,Go工具链中的上传程序(uploader)将从遥测服务器获取一个“上传配置”,其中列出了该周收集的特定事件名称。只有在遥测特定的提案审查过程达成共识后,才会更改该配置。该配置作为一个模块(module)提供,以保护下载的完整性,并保留过去配置的公共记录。然后,上传程序仅上传上传配置中列出的计数器。在幻灯片上,上传程序仅为gopls发送一份报告,仅包含少量计数器,即使磁盘上可能还有更多计数器。报告中包含关于使用gopls的编辑器的统计信息,以及关于完成请求的延迟的信息,还有一个发生了一次的gopls/bug事件,其中包含一个栈跟踪。

请注意,上传的数据中没有事件跟踪或任何用户数据,只有计数器、已在公共上传配置中列出的事件名称,以及Go工具链程序中的函数名称。还要注意,栈跟踪不包括任何函数的参数,只有函数名称,因此没有用户数据。

开源中的遥测可能会在拥有数据访问权限和没有数据访问权限的人之间产生信息失衡。我们希望避免这种情况。请记住奥斯特豪特规则:为了达成共识,我们需要每个人拥有相同的信息。由于Go的遥测上传不包含任何敏感数据,并且是在明确的选择同意的情况下收集的,我们可以完整地重新发布这些报告,以便任何人都可以进行任何数据分析。我们还将发布一些基本的图表,用于做出决策。我们唯一可能看到但没有重新发布的是报告来自哪些IP地址,我们的服务器会将这些信息与报告一起记录。

一个明显的问题是,是否有足够多的人选择启用遥测,以使数据足够准确以做出决策。幸运的是,采样的神奇之处在于可以帮助解决这个问题。

全球大约有300w Go开发者。当系统准备就绪并要求人们启用遥测时,即使只有千分之一的开发者选择参与,也会有3000名开发者,根据我们的图表显示,误差不到3%,置信度为99%。如果全球三分之二的Go开发者启用了遥测,那将是20000个样本,误差不到1%,置信度为99%。除此之外,我们实际上不需要更多的样本。如果我们持续获得更多的报告,我们可以调整上传配置,告诉系统在某个特定的周选择随机不上传任何东西。例如,如果有20万个系统选择了参与,我们可以告诉每个系统在任何给定的周上传的概率为10%。因此,即使我们预计选择参与率会很低,系统应该能够运行得很好,随着选择参与率的提高,Go遥测将从任何给定系统收集更少的数据。当然,这使得每个选择参与的人对我们来说更加重要。目前来说,Go遥测对于你们中的任何人来说都还没有准备好,但当准备好时,我希望你们会选择参与。

在结束之前,我希望你们从演讲中获得以下几点:

首先,Go需要不断变化,特别是随着计算世界的变化。

其次,任何改变的目标都是为了使Go在软件工程中变得更好,尤其是在规模化(scaling)方面。

第三,一旦我们确定了目标,达成共识的下一个最重要的部分是拥有共享数据来做出决策。

第四,Go工具链遥测是增补我们现有调查和代码分析数据的重要数据来源。

最后,在整个演讲中,虽然涉及到了数据和适当的统计,但我们评估的想法、假设和潜在的变化始终始于个人故事和对话。我们喜欢听到这些故事,并与你们所有人讨论如何使用Go,关于什么有效和什么无效。所以,请无论在什么情况下,无论是在会议上、邮件列表上还是在问题跟踪器上,请确保让我们知道Go对你们的工作情况以及存在的问题。我们总是很乐意听到这些。非常感谢。


“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!2023年,Gopher部落将进一步聚焦于如何编写雅、地道、可读、可测试的Go代码,关注代码质量并深入理解Go核心技术,并继续加强与星友的互动。欢迎大家加入!

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语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言第一课 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