Доступ к значениям перечисления в 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, так как вы предположительно обрабатываете не только один вид формы.