我无法理解以下代码中的问题应该是什么:
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参数中的参数一样。
答案 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?。
如果你真的想使用值而不是引用,那么你可能需要为你的结构派生特征Copy
和Clone
。完成后,您可以复制该值并将其返回。
区别在于你的结构:
#[derive(Debug, Copy, Clone)]
enum Foo {
A,
B,
}
有关移动和复制的详细信息,请参阅Move vs Copy in Rust。