首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >仅当两个变量在没有复制时才执行操作?

仅当两个变量在没有复制时才执行操作?
EN

Stack Overflow用户
提问于 2016-12-29 21:27:53
回答 3查看 102关注 0票数 0

我希望在ab不是None的情况下执行操作。我不希望创建复杂结构的副本,这就是为什么struct X不实现Clone的原因。

代码语言:javascript
运行
复制
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);
        }
    }
}

如果我试图编译这段代码,我会得到:

代码语言:javascript
运行
复制
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语句以获得我想要的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-12-29 21:44:12

您需要告诉if let语句只将ab引用到foo.afoo.b,否则if let会将部分部分从借来的值中移出。禁止这样做有两个原因:

  1. 引用是不可变的,因此不能更改。
  2. 始终保证引用指向完全有效的对象。如果您可以将foo.a移动到a中,“偷走”您的贷款人的结构,那么驻留在foo.a中的值将不再有效,从而使foo也无效。

一种解决方案是通过Foo::aFoo::b通过clone()复制值,这是不需要的,而且性能也不是最优的,特别是因为这意味着要进行深入的复制。

我让它在不复制的情况下工作

代码语言:javascript
运行
复制
if let (&Some(ref a), &Some(b)) = (&foo.a, &foo.b) {
    println!("a: {:?}, b: {}", a, b);
}
票数 3
EN

Stack Overflow用户

发布于 2016-12-29 21:59:07

使用一个较小的例子:

代码语言:javascript
运行
复制
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对引用执行与先前的答案相同的匹配类型。

代码语言:javascript
运行
复制
if let (Some(a), Some(b)) = (foo.a.as_ref(), foo.b.as_ref()) {
    println!("a: {}, b: {}", a, b);
}
票数 5
EN

Stack Overflow用户

发布于 2016-12-30 08:39:01

您可以使用变形结构 Foo来代替创建元组:

代码语言:javascript
运行
复制
if let Foo { a: Some(ref a), b: Some(b), .. } = *foo {
    println!("a: {:?}, b: {}", a, b);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41387445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档