开源学村

2022年,从学习Rust开始

Rust 是一个相对新的编程语言(2015年上线),如今已经获得许多的程序员的青睐,成为“最受喜爱编程语言”。罗马并非一日建成,Rust 仍然建立在以往我们所熟悉的事物上。虽然您可能会感到 Rust 与曾经所学过的 Python、JAVA、C++ 等这些语言有很大区别,但它们都是基于您与 CPU 和 NUMA 架构之间互动(不管您是否知道这种互动的存在),因此 Rust 里面一些新的东西又会让你感到熟悉。

现在,我并非一个专业的程序员,没有耐心但是又十分执着去做某件事,当一种编程语言无法按照自己的想法快速地得到我想要的结果,那么下次我也不会首先使用这个语言去完成我想做的事。Rust 语言便尝试平衡这两个互相矛盾的事情:现代的电脑要求安全且标准的结构化代码;而程序员们希望成功的完成一件事情的同时,尽可能地减少工作量。

安装 Rust

可以通过Rust-lang.org 安装 Rust 并且查阅 Rust 的文档,通常情况下,它就像下载并安装 sh.rustup.rs 脚本并运行它一样简单:

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

没有类

Rust 中并没有类(class)这种数据类型而是使用结构体(struct),struct 用于描述一组不同类型数据的数据对象。在 Rust 我们会使用 struct 来创造一个“虚拟对象” :

struct Penguin {
    genus: String,
    species: String,
    extinct: bool,
    classified: u64,
}

您可以像使用类一样使用结构体。例如,定义了 Penguin 结构体后,您可以创建它的实例,像如下例子:

struct Penguin {
    genus: String,
    species: String,
    extinct: bool,
    classified: u64,
}

fn main() {
    let p = Penguin { genus: "Pygoscelis".to_owned(),
         species: "R adeliæ".to_owned(), 
         extinct: false, 
         classified: 1841 };

    println!("Species: {}", p.species);    
    println!("Genus: {}", p.genus);
    println!("Classified in {}", p.classified);
    if p.extinct == true {
        println!("Sadly this penguin has been made extinct.");
    }

}

通过 implstruct 两种数据类型的混合使用,您可以创造包含函数的结构体,并且您也可以实现继承或者其他和类相似的功能。

函数

Rust 中的函数与其他大多数语言中的函数相同,每个函数都代表着一个特定的功能,使用的时候再调用它。同样,至少需要调用主函数 main

使用函数需要用 fn 关键字来声明,后面接着函数名和接受的参数:

fn foo() {
  let n = 8;
  println!("Eight is written as {}", n);
}

通过参数可以将信息从一个函数传递到另一个函数。例如,我们已经创建了 Penguins 类,并且已经将其实例化为 p,当要求将 p 中属性从一个函数传递到另一个函数时,我们需要明确 p 作为接受 Penguins 类型的目标函数:

fn main() {
  let p = Penguin { genus: "Pygoscelis".to_owned(), 
    species: "R adeliæ".to_owned(), 
    extinct: false, classified: 1841 };
  printer(p);
}

fn printer(p: Penguin) {
  println!("Species: {}", p.species);    
  println!("Genus: {}", p.genus);
  println!("Classified in {}", p.classified);
  if p.extinct == true {
      println!("Sadly this penguin has been made extinct.");
  }
}

变量

通常情况下,Rust 创建的是不可变的变量,您不可以改变该变量的值。像这段代码,虽然不起眼,但是不能够被编译的:

fn main() {
 let n = 6;
 let n = 5;
 }

应该使用 mut 关键字,声明一个可变变量,这样子代码才会被成功编译:

fn main() {
 let mut n = 6;
 println!("Value is {}", n);
 n = 5;
 println!("Value is {}", n);
}

编译器

Rust 的编译器,至少就其错误信息提示而言,它是最好编译器之一。当您在 Rust 编程中出错时,Rust 的编译器会提示您的错误所在。实际上,仅仅通过编译器中的错误提示,我就了解了 Rust 中那些细微之处(就我目前对 Rust 的细微差别的了解而言)。即使编译器显示的错误信息太过模糊以至于我们无法直接了解错误所在,我们也可以很容易地在网上找到解释。

最简单的开始 Rust 编程的方法是使用 cargo,Rust 的软件包管理和建立系统:

$ mkdir myproject
$ cd myproject
$ cargo init 

它为我们提供一个项目的基本架构,值得注意的是 src 子目录下的main.rs 文件。打开该文件,并黏贴到文章中的示例代码中去:

struct Penguin {
    genus: String,
    species: String,
    extinct: bool,
    classified: u64,
}

fn main() {
    let p = Penguin { genus: "Pygoscelis".to_owned(), species: "R adeliæ".to_owned(), extinct: false, classified: 1841 };
    printer(p);
    foo();
}

fn printer(p: Penguin) {
    println!("Species: {}", p.species);    
    println!("Genus: {}", p.genus);
    println!("Classified in {}", p.classified);
    if p.extinct == true {
        println!("Sadly this penguin has been made extinct.");
    }
}

fn foo() {
     let mut n = 6;
 println!("Value is {}", n);
 n = 8;
  println!("Eight is written as {}", n);
}

要编译该代码,使用 cargo build 指令:

$ cargo build

为了运行您的项目,需要执行 target 子目录下的二进制文件,或者直接使用 cargo run

$ cargo run
Species: R adeliæ
Genus: Pygoscelis
Classified in 1841
Value is 6
Eight is written as 8

箱子(Crates)

其他语言中,会提供许多方便程序员编程的库和模板。在 Rust 中,库以“箱子(crates)“的形式进行分发和跟踪。Creat.io网站就是一个很好的 crates 社区的注册表

为了在您的 Rust 项目中加入 crates,要在 Cargo.toml 文件中列出它们。例如,要安装一个随机数函数,我们需要使用 rand 箱子,使用用 * 作为通配符以确保我们编译时获得的是最新的版本:

[package]
name = "myproject"
version = "0.1.0"
authors = ["Seth <seth@opensource.com>"]
edition = "2022"

[dependencies]
rand = "*"

在 Rust 代码中使用它,需要在程序顶部用 use 来声明:

use rand::Rng;

创建随机数和控制随机数范围的示例:

fn foo() {
    let mut rng = rand::thread_rng();
    let mut n = rng.gen_range(1..99);

    println!("Value is {}", n);
    n = rng.gen_range(1..99);
    println!("Value is {}", n);
}

您可以使用 cargo run 来运行程序,它会检测到程序的改变并触发新的构建。构建过程中会下载 rand 箱子和它所需要的其他的 crate 箱子,编译器将会编译这段代码,然后运行该代码:

$ cargo run
Updating crates.io index
Downloaded ppv-lite86 v0.2.16
Downloaded 1 crate (22.2 KB) in 1.40s
 Compiling libc v0.2.112
 Compiling cfg-if v1.0.0
 Compiling ppv-lite86 v0.2.16
 Compiling getrandom v0.2.3
 Compiling rand_core v0.6.3
 Compiling rand_chacha v0.3.1
 Compiling rand v0.8.4
 Compiling rustpenguin v0.1.0 (/home/sek/Demo/rustpenguin)
 Finished dev [unoptimized + debuginfo] target(s) in 13.97s
 Running `target/debug/rustpenguin`

Species: R adeliæ
Genus: Pygoscelis
Classified in 1841
Value is 70
Value is 35

Rust Cheat sheet

Rust 是一个非常令人愉悦的语言,这要感谢它对在线注册表的整合、好用的编译器,和它直观的语法,这些让它更像一个现代的编程语言。

但我也要注意,它仍然是一个复杂的编程语言,拥有严格的数据类型,强作用域的变量,和许多内置方法。Rust 是一个值得您去学习的语言,如果您想进一步了解 Rust,你可以下载我们这份Rust Cheat sheet,可以让您快速了解 Rust 的基础知识。越早开始,您会越早学会 Rust。当然,你应该经常练习避免生锈(Rusty)。


翻译:xiaoqi
参考文章:
Learn Rust in 2022

对这篇文章感觉如何?

太棒了
3
不错
1
爱死了
0
不太好
0
感觉很糟
1

You may also like

Leave a reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

More in:开源学村

开源学村

SoCal Linux博览会回归20周年

现在已经是支持和推广FOSS社区的第20个年头了,SCaLE 20x - 南加州Linux博览会将于2023年3月9日至12日在帕萨迪纳会议中心举行。 这个为期4天的年度活动汇集了充满活力的开源用户社 […]
开源学村

如何在Linux上杀死僵尸进程

消灭僵尸进程! 也称为“defunct”或“dead”进程 - 简单来说,僵尸进程是指已经结束,但仍存在于系统进程表中的进程。理想情况下,一旦进程完成其工作/执行,它应该从进程表中清除。但由于某些原因 […]
开源学村

使用 Linux 命令行解决Wordle 问题

你可以使用 Linux 的 grep 命令和 fgrep 命令来解决Wordle 问题(进行筛选排除),grep 命令使用正则表达式进行搜索,fgrep 命令也像 grep 一样搜索文本,但不使用正则表达式,grep 和 fgrep 命令在扫描单词列表时提供了极大的灵活性。
开源学村

如何杀死 Linux 中的僵尸进程

在使用操作系统工作时,要时刻注意保持对系统中进程的掌控。一旦僵尸进程占满了你的资源,就只能依靠重新启动来挽回一切了。所以快来学习用 kill 指令来杀灭僵尸进程吧!