Rust 如何在不获取所有权的情况下替换结构字段的值
(以下) 我有一个第三方API,其中一个结构有一个使用实例并返回新实例的方法;我想将这个API包装在我自己的包装器中,并抽象出在操作中使用结构的细节 这个例子解释了我试图实现的目标:Rust 如何在不获取所有权的情况下替换结构字段的值,rust,ownership,Rust,Ownership,(以下) 我有一个第三方API,其中一个结构有一个使用实例并返回新实例的方法;我想将这个API包装在我自己的包装器中,并抽象出在操作中使用结构的细节 这个例子解释了我试图实现的目标: //第三方API 结构项{ x:u32, } impl项目{ 发布fn增量(自身,金额:u32)->自身{ 项目{x:self.x+金额} } } //我的API 结构容器{ 项目:项目,, } impl容器{ 发布fn增量项目(&mut self,金额:u32){ //这一行导致“无法移出借用的内容”,但这正是我
//第三方API
结构项{
x:u32,
}
impl项目{
发布fn增量(自身,金额:u32)->自身{
项目{x:self.x+金额}
}
}
//我的API
结构容器{
项目:项目,,
}
impl容器{
发布fn增量项目(&mut self,金额:u32){
//这一行导致“无法移出借用的内容”,但这正是我想要做的
自项目=自项目增量(金额);
}
}
虽然现在我理解了这个错误,但我想知道如何在不拥有self
内部Container::increment\u item
的情况下实现它
提议的解决办法:
- 更改
以获取Item::increment
而不是&mut self
:我不能,self
来自板条箱Item::increment
- 使用
(from):不幸的是,构建mem::replace
实例并不那么容易,老实说,我不完全理解项
解决方案是如何工作的mem::replace
- 更改
以获取Container::increment_item
而不是self
:我不想在此过程中使用&mut self
实例,我正试图将我的包装设计成尽可能符合人体工程学的,并且完全消除了这样一个事实,即在更换物品时必须消耗Container
物品
关于如何做的一些想法?还是我在尝试一种不可能的生锈设计?最简单的方法是使用
选项:
- 使用
take
获取项目的所有权
- 然后分配回一些(…)
如果在选项
为空时发生死机,这是完全安全的。不会发生双重破坏,如果您愿意,容器甚至可以保持可用
或在代码中:
// Third-party API
struct Item {
x: u32,
}
impl Item {
pub fn increment(self, amount: u32) -> Self {
Item { x: self.x + amount }
}
}
// My API
struct Container {
item: Option<Item>,
}
impl Container {
pub fn increment_item(&mut self, amount: u32) {
let item = self.item.take().unwrap();
self.item = Some(self.item.increment(amount));
}
}
//第三方API
结构项{
x:u32,
}
impl项目{
发布fn增量(自身,金额:u32)->自身{
项目{x:self.x+金额}
}
}
//我的API
结构容器{
项目:选择,
}
impl容器{
发布fn增量项目(&mut self,金额:u32){
让item=self.item.take().unwrap();
self.item=部分(self.item.increment(amount));
}
}
最简单的方法是使用选项
:
- 使用
获取项目的所有权take
- 然后分配回一些(…)
选项
为空时发生死机,这是完全安全的。不会发生双重破坏,如果您愿意,容器甚至可以保持可用
或在代码中:
// Third-party API
struct Item {
x: u32,
}
impl Item {
pub fn increment(self, amount: u32) -> Self {
Item { x: self.x + amount }
}
}
// My API
struct Container {
item: Option<Item>,
}
impl Container {
pub fn increment_item(&mut self, amount: u32) {
let item = self.item.take().unwrap();
self.item = Some(self.item.increment(amount));
}
}
//第三方API
结构项{
x:u32,
}
impl项目{
发布fn增量(自身,金额:u32)->自身{
项目{x:self.x+金额}
}
}
//我的API
结构容器{
项目:选择,
}
impl容器{
发布fn增量项目(&mut self,金额:u32){
让item=self.item.take().unwrap();
self.item=部分(self.item.increment(amount));
}
}
为什么不将增量项目的签名更改为使用self
而不是&mut self
?@hellow,因为我不想在此过程中使用容器
实例,我正试图将我的包装设计成尽可能符合人体工程学的,并且完全消除了这样一个事实,即在更换物品时必须消耗物品
;我将把它添加到描述中。你可以使用选项来mem::replace
为None
,也可以mem::replace
为零内存区(不安全)。@Boiethios:Whymem::replace
,只要接受!:)请参阅副本,特别是说明如何为您的用例使用选项的副本。为什么不将增量项
的签名更改为使用self
,而不是&mut self
?@hellow,因为我不想在此过程中使用容器
实例,我正试图将我的包装设计成尽可能符合人体工程学的,并且完全消除了这样一个事实,即在更换物品时必须消耗物品
;我将把它添加到描述中。你可以使用选项来mem::replace
为None
,也可以mem::replace
为零内存区(不安全)。@Boiethios:Whymem::replace
,只要接受!:)请参阅副本,特别是说明如何为您的用例使用选项的副本。这是一种方法,但我不喜欢每次必须使用该字段时都使用unwrap
。这看起来是一个很好的解决方案,我会尝试并在有时间时接受答案,谢谢!只是为了学习,我们是否会给出答案,即使这些问题是重复的?或者我们只是把它们标记为重复的吗?@AkinerAlkan:最好标记为重复的,而不是回答;但如果一个复制品只有在得到答案后才被发现,那么就这样吧。我应该先等Shepmaster检查这个问题,他有一个内置的重复检测器;)@Matthieu M:我最近开始积极地为habbit做贡献,我可以说他在rust社区对我来说是一个偶像:)这就是做这件事的方法,但我不喜欢每次我必须使用这个字段时都使用unwrap
。这看起来是一个很好的解决方案,我会尝试一下,有时间的时候接受答案,谢谢!只是为了学习,我们是否会给出答案,即使这些问题是重复的?或者我们只是把它们标记为重复的吗?@AkinerAlkan:最好标记为重复的,而不是重复的