rust 为两个具有不同类型和共同特征的变量运行代码块

kb5ga3dv  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(91)

我有以下(简化)情况:

trait Z {
  fn apply(&self);
}

struct X { ... }
impl Z for X { ... }

struct Y { ... }
impl Z for Y { ... }

fn some_func() {
  ... do_some_stuff_and_initialise_variables
  let x: X = ...;
  let y: Y = ...;
  for z in &[x, y] { // does not work what is the type of z?
     ... doing a lot of stuff involving a lot of the variables initialised in the outer scope
     z.apply();
  }
}

字符串
Rust处理这种情况的方式是什么?
当然,我可以为在for循环中执行的块提取一个泛型函数,但是我必须显式地为所有外部作用域中的变量创建函数参数,这会产生很多开销,所以我想避免这种情况。
我也可以使用dyn Z类型,但这可能意味着运行时开销,我也想避免,因为在这种情况下不需要它。

disbfnqx

disbfnqx1#

不知道你的尝试在哪里失败了,但是宏工作得很好,关键是在初始化的变量已经在作用域中的地方定义它,这样你就可以访问它们:

trait Z {
    fn apply(&self);
}

struct X;
impl Z for X {
    fn apply(&self) {
        println!("apply x")
    }
}

struct Y;
impl Z for Y {
    fn apply(&self) {
        println!("apply y")
    }
}

fn main() {
    let foo = "bar";
    let x: X = X;
    let y: Y = Y;
    macro_rules! doit {
        ($($z:expr),*) => {
            $(
                println!("{foo:?}");
                $z.apply();
            )*
        };
    }
    doit!(x, y);
}

字符串
或者,像建议的那样,你可以使用动态分派:

// …
    for z in [&x as &dyn Z, &y] {
        println!("{foo:?}");
        z.apply();
    }
}

k4emjkb1

k4emjkb12#

另一种解决方案是使用enum模拟动态分派(由于enum_dispatch,这可以自动化)。

trait Z {
    fn apply(&self);
}

struct X;
impl Z for X {
    fn apply(&self) {
        println!("X::apply()")
    }
}

struct Y;
impl Z for Y {
    fn apply(&self) {
        println!("Y::apply()")
    }
}

enum XY {
    X(X),
    Y(Y),
}
impl Z for XY {
    fn apply(&self) {
        match self {
            Self::X(x) => x.apply(),
            Self::Y(y) => y.apply(),
        }
    }
}

fn main() {
    let x = XY::X(X);
    let y = XY::Y(Y);
    for z in &[x, y] {
        z.apply();
    }
}
/*
X::apply()
Y::apply()
*/

字符串

相关问题