33、枚举
枚举
上一个章节学Trait的时候,用的是Ticket这个结构体的例子,Ticket只有三个状态:To-Do
,InProgress
和Done
。
但是Ticket结构体里的status
字段,或new
方法里参数的类型,并不能很好的体现这一点。
#[derive(Debug, PartialEq)]
pub struct Ticket {
title: String,
description: String,
status: String,
}
impl Ticket {
pub fn new(
title: String,
description: String,
status: String
) -> Self {
// [...]
}
}
这都是用String
来表示status
字段。String
是一种非常通用的类型——它不能很好的传达status字段有一组有限的可能值的信息。更糟糕的是,Ticket::new
的调用者,只有在运行时才能发现它们提供的类型是否有效。
所以我们可以使用枚举类型。
enum
枚举是一种可以具有一组固定值的类型,称为variants
(变体)。
在Rust中,使用enum
关键字来定义一个枚举类型:
enum Status {
ToDo,
InProgress,
Done,
}
enum
,就像struct
一样,定义了一种新的Rust类型。
练习
完成/* TODO */
的内容
// TODO: use `Status` as type for `Ticket::status`
// Adjust the signature and implementation of all other methods as necessary.
#[derive(Debug, PartialEq)]
// `derive`s are recursive: it can only derive `PartialEq` if all fields also implement `PartialEq`.
// Same holds for `Debug`. Do what you must with `Status` to make this work.
pub struct Ticket {
title: String,
description: String,
status: Status,
}
/* TODO */
pub enum Status {
/* TODO */
impl Ticket {
pub fn new(title: String, description: String, status: St/* TODO */-> Ticket {
if title.is_empty() {
panic!("Title cannot be empty");
}
if title.len() > 50 {
panic!("Title cannot be longer than 50 bytes");
}
if description.is_empty() {
panic!("Description cannot be empty");
}
if description.len() > 500 {
panic!("Description cannot be longer than 500 bytes");
}
Ticket {
title,
description,
status,
}
}
pub fn title(&self) -> &String {
&self.title
}
pub fn description(&self) -> &String {
&self.description
}
pub fn status(&self) -> &/* TODO */{
&self.status
}
}
这个代码其实挺好弄的,照葫芦画瓢就可以了,不过我发现我最近的代码总是被奇怪的问题通过不了,这次的代码,别的地方写的都挺好的,就#[derive(Debug,PartialEq,Clone,Copy)]
没写Copy
和Clone
,导致发生了所有权失效的问题。这个Copy和Clone一定要写吗?这一块的问题隐藏的很隐蔽?不知道,以后我长点记性好了(
// TODO: use `Status` as type for `Ticket::status`
// Adjust the signature and implementation of all other methods as necessary.
#[derive(Debug, PartialEq)]
// `derive`s are recursive: it can only derive `PartialEq` if all fields also implement `PartialEq`.
// Same holds for `Debug`. Do what you must with `Status` to make this work.
pub struct Ticket {
title: String,
description: String,
status: Status,
}
#[derive(Debug,PartialEq,Clone,Copy)]
pub enum Status {
ToDo,
InProgress,
Done,
}
impl Ticket {
pub fn new(title: String, description: String, status: Status)-> Ticket {
if title.is_empty() {
panic!("Title cannot be empty");
}
if title.len() > 50 {
panic!("Title cannot be longer than 50 bytes");
}
if description.is_empty() {
panic!("Description cannot be empty");
}
if description.len() > 500 {
panic!("Description cannot be longer than 500 bytes");
}
Ticket {
title,
description,
status,
}
}
pub fn title(&self) -> &String {
&self.title
}
pub fn description(&self) -> &String {
&self.description
}
pub fn status(&self) -> &Status{
&self.status
}
}
这一节的学习就先到这里了(
阅读剩余
版权声明:
作者:CN059
链接:https://www.cn059.com/2025/09/16/33%e3%80%81%e6%9e%9a%e4%b8%be.html
文章版权归作者所有,未经允许请勿转载。
THE END