什么时候我们应该使用结构而不是枚举?

时间:2018-02-12 04:58:20

标签: struct enums rust

结构和枚举彼此相似。

何时使用结构而不是枚举更好(反之亦然)?有人可以给出一个明确的例子,使用结构优于使用枚举吗?

3 个答案:

答案 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个对象。