在Rust中创建宏时遇到重复参数不匹配的奇怪情况:
use std::mem;
trait Object {}
#[derive(Debug)]
struct This {}
impl Object for This {}
#[derive(Debug)]
struct That {}
impl Object for That {}
macro_rules! types {
($($fname:ident),*) => {
enum Type {
$($fname),*
}
fn match_it(t: Type, b: Box<Object>) {
let p = match t {
$(
Type::$fname => {
mem::transmute::<Box<Object>, Box<$fname>>(b)
}
),*
};
}
}
}
types!(This, That);
fn main() {}其结果是:
error: match arms have incompatible types [--explain E0308]
--> <anon>:20:21
20 |> let p = match t {
|> ^ expected struct `This`, found struct `That`
<anon>:31:1: 31:20: note: in this expansion of types! (defined in <anon>)
note: expected type `Box<This>`
note: found type `Box<That>`
note: match arm with an incompatible type
--> <anon>:22:33
22 |> Type::$fname => {
|> ^
<anon>:31:1: 31:20: note: in this expansion of types! (defined in <anon>)如果枚举的$fname和Box的$fname共享相同的循环,那么它们不应该是相同的吗?
发布于 2016-07-21 00:25:52
宏将展开为类似以下内容:
enum Type {This, That }
fn match_it(t: Type, b: Box<Object>) {
let p = match t {
Type::This => mem::transmute::<Box<Object>, Box<This>>(b),
Type::That => mem::transmute::<Box<Object>, Box<That>>(b),
}
}p的类型是什么?根据运行时的不同,编译时类型必须不同;这在像Rust这样的静态类型语言中没有意义。
我建议研究一下std::any,这似乎与您可能正在尝试做的事情相似。
发布于 2016-07-21 02:58:38
作为另一种选择,也许您希望在运行时使用Box<Any>进行类型转换
use std::any::Any;
struct N(isize);
struct S(String);
fn main() {
let mut v: Vec<Box<Any>> = Vec::new();
v.push(Box::new(N(17)));
v.push(Box::new(S("foo".to_string())));
let s = v.pop().unwrap().downcast::<S>().unwrap();
let n = v.pop().unwrap().downcast::<N>().unwrap();
println!("Extracted {} and {}", s.0, n.0);
}https://stackoverflow.com/questions/38485681
复制相似问题