带数据的枚举
为变体附加值。
带数据的枚举 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。
变体可以携带数据
到目前为止,我们的变体都只是名称。在 Rust 中,变体还可以在圆括号中携带数据。
这样,单个枚举就可以同时描述值的种类和值本身。
enum Message {
Quit,
Move(i32, i32),
Write(String),
}携带一个值的变体
在圆括号中写入一个类型,即可为变体附加一项数据。
这里的 Celsius(f64) 表示 Celsius 变体携带一个 f64 数字。创建该值时,需要提供这个数字。
enum Temperature {
Celsius(f64),
Fahrenheit(f64),
}
fn main() {
let t = Temperature::Celsius(21.5);
println!("Created a temperature");
}携带多个值的变体
一个变体可以携带多个值,各值之间用逗号分隔。
Move(i32, i32) 存储两个整数,例如 x 坐标和 y 坐标。创建它时需要同时传入这两个值。
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let r = Shape::Rectangle(3.0, 4.0);
println!("Made a rectangle");
}使用 match 提取数据
要读取变体中的数据,请在模式中命名它。这个名称会成为您可以在该分支中使用的变量。
这里的 Shape::Circle(r) 会将存储的半径绑定到 r。
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let s = Shape::Circle(2.0);
match s {
Shape::Circle(r) => println!("radius {}", r),
Shape::Rectangle(w, h) => println!("{} x {}", w, h),
}
}使用绑定的值
数据绑定到名称后,您就可以像使用任何变量一样用它进行计算。
该程序会匹配一个形状并计算其面积,然后从 match 返回结果。
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let s = Shape::Rectangle(3.0, 4.0);
let area = match s {
Shape::Circle(r) => 3.14 * r * r,
Shape::Rectangle(w, h) => w * h,
};
println!("area = {}", area);
}每个变体可以携带不同的数据
每个变体都可以携带不同形式的数据,也可以完全不携带数据。
正是这种灵活性让枚举具有很强的表达能力:一种类型可以表示许多不同的情况。
enum Message {
Quit,
Move(i32, i32),
Write(String),
}类似结构体的变体
变体可以像结构体一样使用带有花括号的命名字段。这样可以清楚地表达每个字段的含义。
构造它时需要为每个字段命名,匹配时也要使用相同的方式。
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
}
fn main() {
let e = Event::Click { x: 10, y: 20 };
match e {
Event::Click { x, y } => println!("click at {},{}", x, y),
Event::KeyPress(c) => println!("key {}", c),
}
}变体中的字符串
变体可以保存 String 这样的所有权数据。通过匹配,您可以访问其中的文本。
注意:按值匹配会将数据移出,不过这里可以这样做,因为我们会立即使用它。
enum Message {
Write(String),
Quit,
}
fn main() {
let m = Message::Write(String::from("hello"));
match m {
Message::Write(text) => println!("text: {}", text),
Message::Quit => println!("bye"),
}
}标准 Option 枚举
Rust 内置的 Option<T> 是一个带数据的枚举:Some(T) 保存一个值,而 None 什么也不保存。
Rust 使用它来表示“可能有一个值”,而不使用 null。匹配它的方式与匹配您自己的枚举相同。
fn main() {
let maybe: Option<i32> = Some(5);
match maybe {
Some(n) => println!("got {}", n),
None => println!("nothing"),
}
}综合运用
这个完整的程序会对温度进行建模,然后在 match 中将摄氏温度读数转换为华氏温度。
请尝试更改变体或它的值,然后重新运行。
enum Temperature {
Celsius(f64),
Fahrenheit(f64),
}
fn main() {
let t = Temperature::Celsius(25.0);
let f = match t {
Temperature::Celsius(c) => c * 9.0 / 5.0 + 32.0,
Temperature::Fahrenheit(f) => f,
};
println!("{} F", f);
}何时使用带数据的变体
当每种情况自然地带有额外信息时,请使用携带数据的变体。
Circle需要一个半径。Write消息需要它的文本。Move需要坐标。
将数据与变体捆绑在一起,可以让相关信息保持在一起,并确保类型安全。
快速检查
检查您对携带数据的枚举的理解。
回顾
您已经学会了枚举变体可以携带数据:一个值、多个值、类似结构体的命名字段,或者完全不携带数据。
您还学会了在 match 模式中为数据命名来读取它,例如 Circle(r)。标准的 Option 类型使用相同的方式。接下来,您将使用守卫和绑定来进一步细化匹配。
常见问题解答
「带数据的枚举」课时是免费的吗?
是的 — 「带数据的枚举」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。
「带数据的枚举」这节课中我会学到什么?
为变体附加值。 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn Rust Coding 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「带数据的枚举」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn Rust Coding 课中编写并运行代码吗?
能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。