Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何在不获取所有权的情况下替换结构字段的值_Rust_Ownership - Fatal编程技术网

Rust 如何在不获取所有权的情况下替换结构字段的值

Rust 如何在不获取所有权的情况下替换结构字段的值,rust,ownership,Rust,Ownership,(以下) 我有一个第三方API,其中一个结构有一个使用实例并返回新实例的方法;我想将这个API包装在我自己的包装器中,并抽象出在操作中使用结构的细节 这个例子解释了我试图实现的目标: //第三方API 结构项{ x:u32, } impl项目{ 发布fn增量(自身,金额:u32)->自身{ 项目{x:self.x+金额} } } //我的API 结构容器{ 项目:项目,, } impl容器{ 发布fn增量项目(&mut self,金额:u32){ //这一行导致“无法移出借用的内容”,但这正是我

(以下)

我有一个第三方API,其中一个结构有一个使用实例并返回新实例的方法;我想将这个API包装在我自己的包装器中,并抽象出在操作中使用结构的细节

这个例子解释了我试图实现的目标:

//第三方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
    来自板条箱
  • 使用
    mem::replace
    (from):
    不幸的是,构建
    实例并不那么容易,老实说,我不完全理解
    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:Why
mem::replace
,只要
接受
!:)请参阅副本,特别是说明如何为您的用例使用选项的副本。为什么不将
增量项
的签名更改为使用
self
,而不是
&mut self
?@hellow,因为我不想在此过程中使用
容器
实例,我正试图将我的包装设计成尽可能符合人体工程学的,并且完全消除了这样一个事实,即在更换物品时必须消耗
物品
;我将把它添加到描述中。你可以使用
选项
mem::replace
None
,也可以
mem::replace
为零内存区(不安全)。@Boiethios:Why
mem::replace
,只要
接受
!:)请参阅副本,特别是说明如何为您的用例使用选项的副本。这是一种方法,但我不喜欢每次必须使用该字段时都使用
unwrap
。这看起来是一个很好的解决方案,我会尝试并在有时间时接受答案,谢谢!只是为了学习,我们是否会给出答案,即使这些问题是重复的?或者我们只是把它们标记为重复的吗?@AkinerAlkan:最好标记为重复的,而不是回答;但如果一个复制品只有在得到答案后才被发现,那么就这样吧。我应该先等Shepmaster检查这个问题,他有一个内置的重复检测器;)@Matthieu M:我最近开始积极地为habbit做贡献,我可以说他在rust社区对我来说是一个偶像:)这就是做这件事的方法,但我不喜欢每次我必须使用这个字段时都使用
unwrap
。这看起来是一个很好的解决方案,我会尝试一下,有时间的时候接受答案,谢谢!只是为了学习,我们是否会给出答案,即使这些问题是重复的?或者我们只是把它们标记为重复的吗?@AkinerAlkan:最好标记为重复的,而不是重复的