例如,考虑:
#[deriving(Eq, Show)]
struct EventOne {
x: f64,
y: f64
}
#[deriving(Eq, Show)]
struct EventTwo {
x: int,
y: int
}
#[deriving(Eq, Show)]
enum ComplexEvent {
A(EventOne, ~str),
B(EventTwo, ~str)
}
我这里有一个复杂的枚举ComplexEvent,它可以是A或B.
我希望能够做到这样的事情:
let x = A(EventOne { x: 0.1, y: 0.1}, ~"Hello");
let z = x.EventOne;
...但这会导致错误:
error: attempted access of field `EventOne` on type `union::ComplexEvent`, but no field with that name was found
let z = x.EventOne;
呃......好吧,作为一个阵列?
error: cannot index a value of type `union::ComplexEvent`
let z = x[0];
好的,为了保证类型安全,你可能需要使用匹配吗?
match x {
A(_, _) => ???,
B(_, _) => ???
}
...
union.rs:28:3: 31:4 error: mismatched types: expected `()` but found `std::result::Result<(),std::io::IoError>` (expected () but found enum std::result::Result)
union.rs:28 match x {
union.rs:29 A(_, _) => ???,
union.rs:30 B(_, _) => ???
union.rs:31 }
error: aborting due to previous error
我可能只是缺少你需要的具体语法,但是我不能为我的生活找到它...
修改:删除=&gt;这个例子的行动因为它似乎让每个人都感到困惑。阅读问题的人!我想从已经存在的枚举中的中获取子值,而不是匹配()枚举并执行println!
答案 0 :(得分:4)
非常简单:
let x = A(EventOne { x: 0.1, y: 0.1 }, ~"Hello");
match x {
A(EventOne{x, y}, s) => println!("{}, {}, {}", x, y, s),
B(EventTwo{x, y}, s) => println!("{}, {}, {}", x, y, s)
}
请注意,这样匹配意味着您要移出~str
字段,因为它不可隐式复制,因此x
会成为部分移动的值,您无法进一步使用它。如果您确实想在匹配后使用该值,则可以通过引用绑定s
:
let x = B(EventTwo { x: 1, y: 2 }, ~"World");
match x {
A(EventOne{x, y}, ref s) => println!("{}, {}, {}", x, y, *s),
B(EventTwo{x, y}, ref s) => println!("{}, {}, {}", x, y, *s)
}
在这种情况下,s
的类型为&~str
,因此您必须取消引用它才能打印它。之后您可以使用x
,因为您没有移出~str
字段,而另一个字段是隐式可复制的,因为它包含隐式可复制数据。
答案 1 :(得分:0)
您需要使用match
,就像在最后一个示例中所做的那样。你在那里得到的错误是由于使用了trace!()
(那是什么?我的Rust没有它),它的返回类型为IoResult<()>
(这是{{1}的typedef但是Rust希望你的表达式有Result<(),std::io::IoError>
类型。
答案 2 :(得分:0)
如果有人提出,我会接受另一个更好的解决方案,但是这样做的方法是:
macro_rules! trace(
($($arg:tt)*) => (
{ ::std::io::stdout().write_line(format_args!(::std::fmt::format, $($arg)*)); }
);
)
#[deriving(Eq, Show)]
struct EventOne {
x: f64,
y: f64
}
#[deriving(Eq, Show)]
struct EventTwo {
x: int,
y: int
}
#[deriving(Eq, Show)]
enum ComplexEvent {
A(EventOne, ~str),
B(EventTwo, ~str)
}
#[test]
fn test_lifetime_scope() {
let x = A(EventOne { x: 0.1, y: 0.1}, ~"Hello");
let y = B(EventTwo { x: 1, y: 2}, ~"Hello2");
let mut z:&EventOne = &EventOne { x: 0.0, y: 0.0 };
match x {
A(ref a, _) => z = a,
B(b, _) => trace!("{}", b)
}
trace!("Accessed values: {}", z);
}
答案 3 :(得分:0)
use std::rand;
use std::rand::Rng;
#[deriving(Eq, Show)]
struct EventOne {
x: f64,
y: f64
}
#[deriving(Eq, Show)]
struct EventTwo {
x: int,
y: int
}
#[deriving(Eq, Show)]
enum ComplexEvent {
A(EventOne, ~str),
B(EventTwo, ~str)
}
#[deriving(Eq, Show)]
enum Event { EventOne, EventTwo }
fn main() {
let mut rng = rand::rng();
let z:ComplexEvent =
if rng.gen() {
A(EventOne { x: 0.1, y: 0.1 }, ~"☺")
} else {
B(EventTwo { x: 100, y: 200 }, ~"☹")
};
match z {
A(e, _) => println!("{}", e),
B(e, _) => println!("{}", e)
}
}