结构和枚举彼此相似。
何时使用结构而不是枚举更好(反之亦然)?有人可以给出一个明确的例子,使用结构优于使用枚举吗?
答案 0 :(得分:4)
解释根本区别的最简单方法可能是枚举包含“变体”,其中一次只能有一个变体,而结构包含一个或多个字段, all 你必须拥有。
因此,您可以使用enum
对错误代码进行建模,一次只能有一个错误代码:
enum ErrorCode {
NoDataReceived,
CorruptedData,
BadResponse,
}
如果需要,枚举变体可以包含值。例如,我们可以像ErrorCode
那样添加一个案例:
enum ErrorCode {
NoDataReceived,
CorruptedData,
BadResponse,
BadHTTPCode(u16),
}
在这种情况下,ErrorCode::BadHTTPCode
的实例始终包含u16
。
这使得每个变体的行为类似于tuple struct or unit struct:
// Unit structs have no fields
struct UnitStruct;
// Tuple structs contain anonymous values.
struct TupleStruct(u16, &'static str);
但是,将它们作为枚举变体写入的优点是ErrorCode
的每个案例都可以存储在ErrorCode
类型的值中,如下所示(对于不相关的结构,这是不可能的) )。
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"
}
然后您可以在枚举上match
确定您获得的变体,并根据它的不同来执行不同的操作。
相比之下,我上面没有提到的第三种类型的结构是最常用的 - 它是每个人在简单地说“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
,必须为其所有字段指定值。
此外,创建response
的值的方式(即HTTPResponse::Something
)表示HTTPResponse
是枚举。它可能看起来像这样:
enum HTTPResponse {
Ok, // 200
BadRequest, // 400
NotFound, // 404
}
答案 1 :(得分:2)
Enums有多种可能性。结构只有一种可能的“类型”。在数学上,我们说结构是产品类型,枚举是产品的总和。如果您只有一种可能性,请使用结构。例如,空格中的点始终将是三个数字。它永远不会是一个字符串,一个函数或其他东西。所以它应该是一个包含三个数字的结构。另一方面,如果您正在构建数学表达式,则它可以(例如)由运算符连接的数字或两个表达式。它有多种可能性,因此它应该是一个枚举。
简而言之,如果结构有效,请使用结构。 Rust可以围绕它进行优化,对于任何阅读代码的人来说,这个值应该被视为更清晰。
答案 2 :(得分:0)
Enum
是一种具有约束值的类型。
enum Rainbow {
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet
}
let color = Red;
match color {
Red => { handle Red case },
// all the rest would go here
}
如果需要,您可以在Enum中存储数据。
enum ParseData {
Whitespace,
Token(String),
Number(i32),
}
fn parse(input: String) -> Result<String, ParseData>;
结构是一种表示事物的方式。
struct Window {
title: String,
position: Position,
visible: boolean,
}
现在,您可以制作代表屏幕上窗口的新Window
个对象。