如何在不调用克隆的情况下从盒装值中移出多个值?

时间:2015-12-13 20:49:46

标签: rust

我有一个盒装元组来避免递归。但是,当我对元组进行模式匹配时,我似乎无法获得两个元组值。为了说明我的问题,请the following code

    protected override IObservable<bool> IsDirty() {
        return this.WhenAnyValue 
        (x => x.Firstname,
         x => x.LastName
        (f1, f2) => 
        f1 != this.Model.FirstName
        || f2 != this.Model.LastName
        );
    }

    protected override void SaveModel() {
        Model.FirstName = this.FirstName;
        Model.LastName = this.LastName;
        Save(Model); 
        // want to force IsDirty to re-evaluate here and return false.
    }

我收到此错误:

#[derive(Clone, PartialEq, Debug)]
enum Foo {
    Base,
    Branch(Box<(Foo, Foo)>),
}

fn do_something(f: Foo) -> Foo {
    match f {
        Foo::Base => Foo::Base,
        Foo::Branch(pair) => {
            let (f1, f2) = *pair;
            if f2 == Foo::Base {
                f1
            } else {
                f2
            }
        }
    }
}

fn main() {
    let f = Foo::Branch(Box::new((Foo::Base, Foo::Base)));
    println!("{:?}", do_something(f));
}

我读过有关盒装语法的内容,但如果可能的话,我想避免使用不稳定的功能。感觉就像唯一的答案是将error[E0382]: use of moved value: `pair` --> src/main.rs:11:22 | 11 | let (f1, f2) = *pair; | -- ^^ value used here after move | | | value moved here | = note: move occurs because `pair.0` has type `Foo`, which does not implement the `Copy` trait 重新定义为

Branch

但这似乎避免回答这个问题(在这一点上,这主要是一个思想练习)。

3 个答案:

答案 0 :(得分:3)

这在issue 16223中进行了跟踪。好消息是non-lexical lifetimes已解决该问题,原始代码按原样编译:

#![feature(nll)]

#[derive(Clone, PartialEq, Debug)]
enum Foo {
    Base,
    Branch(Box<(Foo, Foo)>),
}

fn do_something(f: Foo) -> Foo {
    match f {
        Foo::Base => Foo::Base,
        Foo::Branch(pair) => {
            let (f1, f2) = *pair;
            if f2 == Foo::Base {
                f1
            } else {
                f2
            }
        }
    }
}

fn main() {
    let f = Foo::Branch(Box::new((Foo::Base, Foo::Base)));
    println!("{:?}", do_something(f));
}

答案 1 :(得分:1)

分两步进行拆箱:

fn do_something(f: Foo) -> Foo {
    match f {
        Foo::Base => Foo::Base,
        Foo::Branch(pair) => {
            let pair = *pair;
            let (f1, f2) = pair;
            if f2 == Foo::Base {
                f1
            } else {
                f2
            }
        }
    }
}

答案 2 :(得分:1)

括在花括号内也行。

fn do_something(f: Foo) -> Foo {
    match f {
        Foo::Base => Foo::Base,
        Foo::Branch(pair) => {
            let (f1, f2) = { *pair };
            if f2 == Foo::Base {
                f1
            } else {
                f2
            }
        }
    }
}