我希望在a和b不是None的情况下执行操作。我不希望创建复杂结构的副本,这就是为什么struct X不实现Clone的原因。
use std::sync::{Arc, Mutex};
use std::cell::RefCell;
#[derive(Debug)]
struct X {
d: u32,
}
struct Foo {
a: Option<X>,
b: Option<u32>,
c: u32,
}
fn main() {
let smart_ptr = Arc::new(Mutex::new(RefCell::new(Foo {
a: Some(X { d: 1 }),
b: Some(2),
c: 3,
})));
{
let lock = smart_ptr.lock().unwrap();
let foo = lock.borrow();
if let (Some(ref a), Some(b)) = (foo.a, foo.b) {
println!("a: {:?}, b: {}", a, b);
}
}
}如果我试图编译这段代码,我会得到:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:25:42
|
25 | if let (Some(ref a), Some(b)) = (foo.a, foo.b) {
| ^^^ cannot move out of borrowed content如何在没有编译错误的情况下修复if语句以获得我想要的?
发布于 2016-12-29 21:44:12
您需要告诉if let语句只将a和b引用到foo.a和foo.b,否则if let会将部分部分从借来的值中移出。禁止这样做有两个原因:
foo.a移动到a中,“偷走”您的贷款人的结构,那么驻留在foo.a中的值将不再有效,从而使foo也无效。一种解决方案是通过Foo::a和Foo::b通过clone()复制值,这是不需要的,而且性能也不是最优的,特别是因为这意味着要进行深入的复制。
我让它在不复制的情况下工作
if let (&Some(ref a), &Some(b)) = (&foo.a, &foo.b) {
println!("a: {:?}, b: {}", a, b);
}发布于 2016-12-29 21:59:07
使用一个较小的例子:
struct Foo {
a: Option<String>,
b: Option<String>,
}
fn main() {
let foo = &Foo {
a: Some("hi".into()),
b: Some("world".into()),
};
if let (Some(a), Some(b)) = (foo.a, foo.b) {
println!("a: {}, b: {}", a, b);
}
}可以使用Option::as_ref对引用执行与先前的答案相同的匹配类型。
if let (Some(a), Some(b)) = (foo.a.as_ref(), foo.b.as_ref()) {
println!("a: {}, b: {}", a, b);
}发布于 2016-12-30 08:39:01
您可以使用变形结构 Foo来代替创建元组:
if let Foo { a: Some(ref a), b: Some(b), .. } = *foo {
println!("a: {:?}, b: {}", a, b);
}https://stackoverflow.com/questions/41387445
复制相似问题