什么时候应该使用结构而不是枚举? [英] When should we use a struct as opposed to an enum?
问题描述
结构和枚举彼此相似。
Structs and enums are similar to each other.
什么时候使用结构而不是枚举会更好(反之亦然)?有人可以举一个清晰的例子,说明使用结构胜于使用枚举吗?
When would it be better to use a struct as opposed to an enum (or vice-versa)? Can someone give a clear example where using a struct is preferable to using an enum?
推荐答案
也许是解释基本原理的最简单方法区别在于,一个枚举包含变体,一次只能拥有一个,而一个结构包含一个或多个字段,必须全部具有 all 。
Perhaps the easiest way to explain the fundamental difference is that an enum contains "variants", of which you can only ever have one at a time, whereas a struct contains one or more fields, all of which you must have.
因此,您可以使用枚举
来建模类似错误代码的代码,一次只能有一个错误代码:
So you might use an enum
to model something like an error code, where you can only ever have one at a time:
enum ErrorCode {
NoDataReceived,
CorruptedData,
BadResponse,
}
枚举变量可以根据需要包含值。例如,我们可以像这样向 ErrorCode
添加一个案例:
Enum variants can contain values if needed. For example, we could add a case to ErrorCode
like so:
enum ErrorCode {
NoDataReceived,
CorruptedData,
BadResponse,
BadHTTPCode(u16),
}
在这种情况下, ErrorCode :: BadHTTPCode
的实例始终包含 u16
。
In this case, an instance of ErrorCode::BadHTTPCode
always contains a u16
.
这使每个变体的行为都类似于元组结构或单元结构:
This makes each individual variant behave kind of like either a tuple struct or unit struct:
// Unit structs have no fields
struct UnitStruct;
// Tuple structs contain anonymous values.
struct TupleStruct(u16, &'static str);
但是,将它们编写为枚举变量的好处是每个<$ c $可以将c> ErrorCode 存储为 ErrorCode
类型的值,如下所示(对于不相关的结构,这是不可能的)。
However, the advantage of writing them as enum variants is that each of the cases of ErrorCode
can be stored in a value of type ErrorCode
, as below (this would not be possible with unrelated structs).
fn handle_error(error: ErrorCode) {
match error {
ErrorCode::NoDataReceived => println!("No data received."),
ErrorCode::CorruptedData => println!("Data corrupted."),
ErrorCode::BadResponse => println!("Bad response received from server."),
ErrorCode::BadHTTPCode(code) => println!("Bad HTTP code received: {}", code)
};
}
fn main() {
handle_error(ErrorCode::NoDataReceived); // prints "No data received."
handle_error(ErrorCode::BadHTTPCode(404)); // prints "Bad HTTP code received: 404"
}
然后您可以<$在枚举上进行c $ c> match 以确定给您哪种变体,并根据其变体执行不同的操作。
You can then match
on the enum to determine which variant you've been given, and perform different actions depending on which one it is.
相比之下,我上面没有提到的第三种结构类型是最常用的-这是每个人在简单地说结构时所指的结构类型
By contrast, the third type of struct that I didn't mention above is the most commonly used - it's the type of struct that everyone is referring to when they simply say "struct".
struct Response {
data: Option<Data>,
response: HTTPResponse,
error: String,
}
fn main() {
let response = Response {
data: Option::None,
response: HTTPResponse::BadRequest,
error: "Bad request".to_owned()
}
}
请注意,在这种情况下,要创建 Response
,必须为其所有字段提供值。
Note that in that case, in order to create a Response
, all of its fields must be given values.
此外,的值响应的方式
已创建(即 HTTPResponse :: Something
)表示 HTTPResponse
是一个枚举。可能看起来像这样:
Also, the way that the value of response
is created (i.e. HTTPResponse::Something
) implies that HTTPResponse
is an enum. It might look something like this:
enum HTTPResponse {
Ok, // 200
BadRequest, // 400
NotFound, // 404
}
这篇关于什么时候应该使用结构而不是枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!