不能移出`[Foo; 2]`类型,非复制数组

时间:2017-12-30 21:33:52

标签: rust

我无法理解以下代码中的问题应该是什么:

extern crate rand;
use rand::*;

#[derive(Debug)]
enum Foo {
    A,
    B,
}

static FOOS: [Foo; 2] = [Foo::A, Foo::B];

fn random_foo() -> Foo {
    let i = rand::thread_rng().gen_range(0, FOOS.len());
    FOOS[i]
}

fn main() {
    println!(
        "First: {:?} Second: {:?} Random: {:?}",
        FOOS[0],
        FOOS[1],
        random_foo()
    );
}

我收到错误:

error[E0508]: cannot move out of type `[Foo; 2]`, a non-copy array
  --> src/main.rs:14:5
   |
14 |     FOOS[i]
   |     ^^^^^^^ cannot move out of here

仅使用println!()的前两部分并删除fn random_foo(),代码会进行编译。我看不出random_foo()做什么不同,值得编译错误。它只访问FOOS的元素并尝试返回值,就像main()中print参数中的参数一样。

1 个答案:

答案 0 :(得分:4)

在您的示例中,您尝试返回。返回FOOS[1]后,将复制该值以进行返回,但在您的情况下,您的结构将无法复制。

最简单的方法是使用引用:

extern crate rand;
use rand::*;

#[derive(Debug)]
enum Foo {
    A,
    B,
}
//Your array still uses two values of type Foo
static FOOS: [Foo; 2] = [Foo::A, Foo::B];

/*
 * random_foo() now returns a reference. So the value in FOOS
 * is no longer borrowed.
 */
fn random_foo() -> &'static Foo {
    let i = rand::thread_rng().gen_range(0, FOOS.len());
    &FOOS[i]
}

fn main() {
    println!(
        "First: {:?} Second: {:?} Random: {:?}",
        FOOS[0],
        FOOS[1],
        random_foo()
    );
}

请参阅Rust book about ownership并借用。

请参阅示例中使用的Rust book about static lifetime

println!宏可以使用您的变量而无需获取所有权或复制,它将它们用作引用。宏不是函数,在这一点上它们可以与C ++宏进行比较。在编译之前,它们由相应的代码替换。例如,在宏中,可以使用运算符的地址。有关详细信息,请参阅Does println! borrow or own the variable?

如果你真的想使用值而不是引用,那么你可能需要为你的结构派生特征CopyClone。完成后,您可以复制该值并将其返回。

区别在于你的结构:

#[derive(Debug, Copy, Clone)]
enum Foo {
    A,
    B,
}

有关移动和复制的详细信息,请参阅Move vs Copy in Rust