在 Rust 中,vector 通常指的是 Vec<T>。
中文可以叫:动态数组 / 可变长数组。。。也有人直译叫:向量
在 Rust 中,vector 通常指的是 Vec<T>。
中文可以叫:动态数组 / 可变长数组。。。也有人直译叫:向量
| Rust 概念 | Java 大概对应 | 说明 |
|---|---|---|
crate |
Maven artifact / jar 包 / Java 模块 | Rust 的最小编译单元,也是依赖发布单位 |
package |
Maven 项目 / Gradle project | 一个 Rust package 里可以包含一个或多个 crate |
Cargo.toml |
pom.xml / build.gradle |
管理依赖、版本、构建配置 |
cargo |
Maven / Gradle | Rust 官方构建、依赖、测试、发布工具 |
crates.io |
Maven Central | Rust 官方/主流 crate 仓库 |
module / mod |
Java package 的一部分概念 | Rust 代码组织方式,不等于 Java package |
use |
import |
引入模块、类型、函数 |
pub |
public |
控制可见性 |
trait |
interface | 定义能力/行为,类似 Java 接口 |
impl |
class implements interface / 方法实现 | 给类型实现方法或 trait |
struct |
class / record / DTO | Rust 的结构体,只有数据字段,没有继承 |
enum |
enum + sealed class | Rust enum 比 Java enum 强很多,可携带数据 |
workspace |
Maven multi-module project | 多个 package 放在一个工程里统一管理 |
if let 获取通过等号分隔的一个模式和一个表达式。它的工作方式与 match 相同,这里的表达式对应 match 而模式则对应第一个分支。
#![allow(unused)]
fn main() {
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
let coin = Coin::Penny;
let mut count = 0;
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
}
Rust 有一个叫做 match 的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。模式可由字面量、变量、通配符和许多其他内容构成;
让我们用它们来作为一个使用 match 的例子!我们可以编写一个函数来获取一个未知的硬币,并以一种类似验钞机的方式,确定它是何种硬币并返回它的美分值,如示例 6-3 中所示。
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
这行代码:
#![allow(unused)]
作用是:告诉 Rust 编译器:不要提示“未使用”相关的警告。
让我们看看一个需要诉诸于代码的场景,来考虑为何此时使用枚举更为合适且实用。假设我们要处理 IP 地址。目前被广泛使用的两个主要 IP 标准:IPv4(version four)和 IPv6(version six)。这是我们的程序可能会遇到的所有可能的 IP 地址类型:所以可以 枚举 出所有可能的值,这也正是此枚举名字的由来。
可以通过在代码中定义一个 IpAddrKind 枚举来表现这个概念并列出可能的 IP 地址类型,V4 和 V6。这被称为枚举的 成员(variants):
enum IpAddrKind {
V4,
V6,
}
现在 IpAddrKind 就是一个可以在代码中使用的自定义数据类型了。
枚举值
可以像这样创建 IpAddrKind 两个不同成员的实例:
let four = IpAddrKind::V4; let six = IpAddrKind::V6;
定义struct的方法
让我们把前面实现的获取一个 Rectangle 实例作为参数的 area 函数,改写成一个定义于 Rectangle 结构体上的 area 方法,如示例 5-13 所示:
文件名: src/main.rs
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
示例 5-13:在 Rectangle 结构体上定义 area 方法
结构体和我们在“元组类型”章节论过的元组类似。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。
通过派生 trait 增加实用功能
如果能够在调试程序时打印出 Rectangle 实例来查看其所有字段的值就更好了。如下示例像前面章节那样尝试使用 println! 宏。但这并不行。
文件名: src/main.rs
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {}", rect1);
}
当我们运行这个代码时,会出现带有如下核心信息的错误:
error[E0277]: `Rectangle` doesn't implement `std::fmt::Display`
字符串 slice
字符串 slice(string slice)是 String 中一部分值的引用,它看起来像这样:
fn main() {
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
}
字符串字面量就是 slice —— 类型为 &str
还记得我们讲到过字符串字面量被储存在二进制文件中吗?现在知道 slice 了,我们就可以正确地理解字符串字面量了:
let s = "Hello, world!";
这里 s 的类型是 &str :它是一个指向二进制程序特定位置的 slice。这也就是为什么字符串字面量是不可变的;&str 是一个不可变引用。
详情查看:https://www.rustwiki.org.cn/zh-CN/book/ch04-03-slices.html