Доступ к значениям перечисления в Rust

struct Point { x: f64, y: f64 }

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point)
}

let my_shape = Shape::Circle(Point {x: 0.0, y: 0.0}, 10.0);

Я хочу распечатать второе свойство круга, которое здесь 10.0. Я пробовал my_shape.last и my_shape.second, но не работал.

Что делать, чтобы распечатать 10.0 в этом случае?

Спасибо

Ответ 1

Я не уверен, есть ли лучший способ сделать это, но вы можете использовать сопоставление с образцом:

use std;

type point = {x: float, y: float};
enum shape {
    circle(point, float),
    rectangle(point, point)
}

fn main() {
    let my_shape = circle({x: 0.0, y: 0.0}, 10.0);
    alt my_shape {
        circle(_, value) {
            std::io::println(#fmt("value: %f", value));
        }
    }
}

Пример вывода:

value: 10

Ответ 2

Поскольку вас интересует только один из вариантов, вы можете использовать выражение if let:

struct Point { x: f64, y: f64 }

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point)
}

fn main() {
    let my_shape = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);

    if let Shape::Circle(_, radius) = my_shape {
        println!("value: {}", radius);
    }
}

Это означает, что "если my_shape можно разрушить в Circle, ничего не делать с первым индексом, а привязать значение второго индекса к radius".

Ответ 3

Из учебника Rust (выделено мной):

Для типов перечислений с несколькими вариантами деструктурирование - единственный способ чтобы получить их содержимое. Все конструкторы вариантов могут использоваться как шаблонов, как в этом определении области:

fn area(sh: shape) -> float {
    alt sh {
        circle(_, size) { float::consts::pi * size * size }
        rectangle({x, y}, {x: x2, y: y2}) { (x2 - x) * (y2 - y) }
    }
}

http://doc.rust-lang.org/doc/tutorial.html#enum-patterns

Если вы хотите писать функции, которые могут работать с несколькими типами с разными представлениями, посмотрите на интерфейсы:

http://doc.rust-lang.org/doc/tutorial.html#interfaces

Ответ 4

Вот еще один способ сделать это:

use std;

type point = {x: float, y: float};
enum shape {
    circle(point, float),
}

fn main() {
    let circle(_, radius) = circle({x: 0.0, y: 0.0}, 10.0);
    std::io::println(#fmt("value: %f", radius));
}

Это работает только в том случае, если шаблон let неопровержимо, например, если тип перечисления, который вы используете, имеет только один вариант. Чтобы выполнить эту работу, мне пришлось удалить неиспользуемый вариант rectangle.

В случаях, когда у вас есть несколько вариантов, вы, вероятно, захотите получить полное выражение alt, так как вы предположительно обрабатываете не только один вид формы.