防止值在通用匹配中掉落

Preventing value from dropping inside generic match

当试图创建从 match 语句中继承特征的对象时,我发现有必要为每种类型的匹配对象定义不同的外部变量。有必要在匹配之外声明变量,这样声明就不会超出范围。

无法使用类型为 Trt 的单个外部变量,因为 Trt 未确定大小。有什么方法可以匹配 return 一个实现 Trt 的对象,而无需恢复到这种提前定义大量变量的丑陋方法?

这是一个问题示例:

enum Enm {
    X1,
    X2,
    X3
}

trait Trt {
    fn foo(&self) -> &'static str;
}

struct A{}
impl Trt for A{
    fn foo(&self) -> &'static str { "A" }
}

struct B{}
impl Trt for B{
    fn foo(&self) -> &'static str { "B" }
}

struct C{}
impl Trt for C{
    fn foo(&self) -> &'static str { "C" }
}

fn main() {
    let x = Enm::X3;

    let mut temp;
    let mut temp2;
    let mut temp3;
    let gen = match x {
        Enm::X1 => {
            temp = A{};
            &mut temp as &mut Trt
        },
        Enm::X2 => {
            temp2 = B{};
            &mut temp2 as &mut Trt
        },
        Enm::X3 => {
            temp3 = C{};
            &mut temp3 as &mut Trt
        },
    };

    println!("{}", gen.foo());
}

您创建的对象需要有一个所有者。普通引用 & 不能是所有者,这就是为什么您需要在代码中使用 temp/temp2/temp3 作为您在 [=15= 中创建的对象的所有者]武器

拥有特征对象的最简单方法是使用 Box,如下所示:

// definitions omitted...
fn main() {
    let x = Enm::X3;

    let gen = match x {
        Enm::X1 => {
            Box::new(A{}) as Box<Trt>
        },
        Enm::X2 => {
            Box::new(B{}) as Box<Trt>
        },
        Enm::X3 => {
            Box::new(C{}) as Box<Trt>
        },
    };

    println!("{}", gen.foo());
}

在 match 子句之后,现在 gen 拥有创建的特征对象,因此您不必再定义临时对象。