gpt4 book ai didi

rust - 无法移出 `&` 指针的解除引用

转载 作者:行者123 更新时间:2023-11-29 08:30:31 24 4
gpt4 key购买 nike

我有以下代码

pub struct PropertyDeclarationBlock {
pub declarations: Arc<Vec<(PropertyDeclaration, PropertyDeclarationImportance)>>
}

impl PropertyDeclarationBlock {
pub fn select_declarations(&self) -> Arc<Vec<PropertyDeclaration>> {
Arc::new(self.declarations.clone().map_in_place(|p| {
let (declaration, _) = p;
declaration
}))
}

}

我希望能够在 PropertyDeclarationBlock 上调用 .select_declarations() 并让它返回声明的克隆但它不是 Arc Vec (PropertyDeclaration, PropertyDeclarationImportance) 只是 Arc Vec PropertyDeclaration,换句话说返回一个 PropertyDeclaration 的向量,而不是前面的元组。

前一个无法编译,因为我收到以下错误:

error: cannot move out of dereference of `&`-pointer
Arc::new(self.declarations.clone().map_in_place(|p| {
^~~~~~~~~~~~~~~~~~~~~~~~~

据我了解,由于该函数将 self 作为参数,因此它将获得它的所有权。因为我更愿意使用 burrow self 函数,所以我使用了 &。

编辑

这是实现新功能后的错误信息:

error: cannot move out of dereference of `&`-pointer
Arc::new(self.declarations.iter().map(|&(declaration, _)| declaration).collect())
^~~~~~~~~~~~~~~~~
note: attempting to move value to here (to prevent the move, use `ref declaration` or `ref mut declaration` to capture value by reference)
Arc::new(self.declarations.iter().map(|&(declaration, _)| declaration).collect())
^~~~~~~~~~~

我尝试按照错误消息的建议在声明之前应用 ref 关键字,但没有帮助。

最佳答案

self.declarations.clone() 克隆 Arc,而我相信您打算克隆 Vec。为了解析对 map_in_place 的调用,编译器自动取消对 Arc 的引用,以便能够调用在 Vec 上定义的方法。编译器知道如何取消引用 Arc 因为 Arc 实现了 Deref . deref 返回一个借用的指针,这就是错误的来源。要克隆 Vec,我们必须显式取消引用 Arc:(*self.declarations).clone()

然而,map_in_place在这种情况下不合适,因为 (PropertyDeclaration, PropertyDeclarationImportance) 的大小与 PropertyDeclaration 不同(除非 PropertyDeclarationImportance 的大小为零,这可能不是这种情况),这是文档所必需的。它失败并显示类似于此的消息:

task '<main>' failed at 'assertion failed: mem::size_of::<T>() == mem::size_of::<U>()', /build/rust-git/src/rust/src/libcollections/vec.rs:1805

这是一个正确的实现:

impl PropertyDeclarationBlock {
pub fn select_declarations(&self) -> Arc<Vec<PropertyDeclaration>> {
Arc::new(self.declarations.iter().map(|&(declaration, _)| declaration).collect())
}
}

在这里,我们使用 iterVec 上创建向量项的迭代器。这将返回 Items , 它实现了 Iterator在不可变引用上。

然后,我们使用 map延迟映射 (PropertyDeclaration, PropertyDeclarationImportance)PropertyDeclaration。请注意我们如何解构元组 闭包参数列表中的引用(这在 fn 中也有效)而不是使用 let 语句。

最后,我们使用 collect为此序列创建一个新的收集容器。 collect 的结果是通用的;它可以是任何实现 FromIterator 的类型. Vec 实现了 FromIterator,编译器从方法的签名中推断出 Vec

关于rust - 无法移出 `&` 指针的解除引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26569620/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com