Duk*_*Cat 5 reference rust borrowing
我正在尝试理解 Rust 的所有权模型。我试图在结构体上调用函数时传递对包含对象的引用。
这是我的结构:
pub struct Player {}
impl Player {
pub fn receive(self, app: &App) {
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,receive需要一个对象的引用App。
pub struct App {
pub player: Player,
}
impl App {
pub fn sender(self) {
// how to call player.test() and pass self as a reference?
self.player.receive(&self);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码给了我“使用部分移动的值:self”。这是有道理的,因为App具有移动语义,因此该值sender在调用函数时被移动到函数中。
如果我更改它以便sender需要引用self,我会得到“无法移出借用的内容”,这也是有道理的,因为我们self在进入sender函数时借用了引用。
那我该怎么办?App我明白为什么我不能存储对inside 的引用Player,因为这会导致双向链接结构。但我应该能够借用一个引用并对其执行操作,不是吗?
我在官方教程中没有找到答案。
我通过self作为参考传递来解决它receive。但是如果我想app在 中可变怎么办receive?我不能以self可变的方式传递,sender因为我也player以可变的方式借用。
在调用该方法之前取消关联
player。self
是将其player放入Option:
impl App {
pub fn sender(&mut self) {
let mut player = self.player.take();
player.receive(&mut self);
self.player = Some(player);
}
}
Run Code Online (Sandbox Code Playgroud)
最后一项资源是使用RefCell.
因为具有移动语义,所以在调用函数时
App该值被移动到函数中。sender
确实它已被移入sender,但这不是此消息的目的。因为按值Player::receive获取self,所以您实际上必须分解app并移出player它才能调用receive. 那时,app现在已半成形;它没有有效值player!如果receive尝试访问app.player,它将使用无效内存。
“无法移出借用的内容”[...] 因为我们借用了
self进入该sender函数时的引用。
是的,这与上面相关。因为我们借用了 an App,所以我们无法移出player它,从而使App处于无效状态。
我应该能够借用一个引用并对其执行操作,不是吗?
你可以,只要你所引用的东西在那时已经完全形成了。上面的阐述中还有两个提示:
如果
receive尝试访问app.player
如果您不访问app.playerin receive,请重构代码以传递 的其他组件App而不是整个容器。也许你有一些GameState真正想要传递的东西。
使 处于
App无效状态
您可以使用类似的方法将不同的内容mem::replace放入. 然后它仍然是完全(但不同)形成的,并且可以再次引用它。 Playerapp
当然,更实际的解决方案是改为接受引用( &self)。
但是如果我想
app在 中可变怎么办receive?
是的!你会得到“不能*self一次借用多次”。然而,解决方案实际上基本相同!在调用该方法之前将其分解为App更小的、不重叠的部分或解除关联。playerself
| 归档时间: |
|
| 查看次数: |
7646 次 |
| 最近记录: |