Rust中在match语句内部解构Option<Box<_>>

9

我有一个大对象,需要将其装箱到另一个对象中,但并不总是需要。因此,我想使用 if 语句获取可选的装箱临时结构,但我不确定如何同时解构和取消引用。

例子:

pub struct TempStructure {
    lots_of_data: [u64; 64],
}
pub struct Structure {
    pending_removal: Option<Box<(TempStructure, bool)>>,
}
impl Structure {
    pub fn do_somthing(&mut self) {
        // How do I destructure the Option and dereference the Box to get TempStructure?
        if let Some((temp_structure, some_boolean)) = self.pending_removal.take() { 
            // Do something with temp_structure and some_boolean
        }
    }
}

当我执行这个 ^^^ 时,出现了一个期望的结构体`std::boxed::Box`,但是找到了元组的错误。
2个回答

9

在匹配后取消引用盒子:

if let Some(inner) = self.pending_removal.take() {
    let (temp_structure, some_boolean) = *inner;
    // Do something with temp_structure and some_boolean
}

(演示平台)

如果您认为这有点笨重,那么您是正确的。在夜间版中,您可以使用不稳定的box_patterns功能来启用更好的语法(尽管这可能永远不会稳定下来):

if let Some(box (temp_structure, some_boolean)) = self.pending_removal.take() {
    // Do something with temp_structure and some_boolean
}

(游乐场)


我知道box语法,但我不知道它被用于这个目的。谢谢你展示了这个! - Zyansheep
@Zyansheep,我记得你无法移动出 &mut self - Netwave

7
您可以通过在 take() 后添加 .as_deref() 来解决这个问题:
pub struct TempStructure {
    lots_of_data: [u64; 64],
}
pub struct Structure {
    pending_removal: Option<Box<(TempStructure, bool)>>,
}
impl Structure {
    pub fn do_somthing(&mut self) {
        // How do I destructure the Option and dereference the Box to get TempStructure?
        if let Some((temp_structure, some_boolean)) = self.pending_removal.take().as_deref() { 
            // Do something with temp_structure and some_boolean
        }
    }
}

Box<T> 解引用为 &Tas_deref() 解引用 Option 的值,因此它可以从你的 Option<Box<T>> 中得到一个 &T

编辑:另一种选择是将 Box 解引用以将其值移出:

        if let Some((temp_structure, some_boolean)) = self.pending_removal.take().map(|boxed| *boxed) { 
            // assignments just for demonstration purposes that we now get
            // owned values rather than references.
            let _: TempStructure = temp_structure;
            let _: bool = some_boolean;
        }

我认为我想要将元组移出盒子,而不仅仅是获取临时对象的引用。是否有任何方法可以使用.as_deref()函数来实现? - Zyansheep
1
您可以通过取消引用来移出盒子: if let Some((temp_structure, some_boolean)) = self.pending_removal.take().map(|boxed| *boxed) { let _: TempStructure = temp_structure; let _: bool = some_boolean; // 对temp_structure和some_boolean进行操作 } - sebpuetz
那将是一个不错的选择添加到答案中。 - trent
我编辑了答案,但在SO上写评论方面缺乏一些经验,你有什么办法可以修复上面评论中的代码块吗? - sebpuetz
2
我认为注释不应该有多行代码块。 - Zyansheep
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接