为什么在调用一个按值获取 self 的方法时会借用一个移动的值,该方法的参数也调用一个方法?

编程入门 行业动态 更新时间:2024-10-22 04:26:06
本文介绍了为什么在调用一个按值获取 self 的方法时会借用一个移动的值,该方法的参数也调用一个方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我遇到了一个问题,该问题迫使我将一个漂亮的 oneliner 拆分为带有中间 let 的 {} 块.我根本不清楚这样做的原因.我能够在这个最小的例子中隔离问题:

I ran into an issue that forces me to split a nice oneliner into a {} block with an intermediate let. The reason for this isn't clear to me at all. I was able to isolate the issue in this minimal example:

struct AB { a: u8, b: u8, } impl AB { fn foo(&self) -> String { String::from("foo") } fn bar(self, x: String) -> String { format!("{} - {} - {}!", x, self.a, self.b) } } fn main() { let x = AB { a: 3, b: 5 }; let result = x.bar(x.foo()); println!("{}", result); }

我的印象是 bar 函数的参数会在调用 bar 之前 被评估.foo 在执行过程中借用了 x,但是当它返回它的 String 时,借用就完成了,因为 String 是不是带有 x 生命周期的引用.当 bar 被调用时,foo 的借用应该结束.

I was under the impression that the arguments to the bar function would be evaluated before calling bar. foo borrows x during its execution, but when it returns its String, the borrow is finished, as String is not a reference bearing x's lifetime. When bar gets called, foo's borrow should be over.

然而,编译器不同意:

error[E0382]: borrow of moved value: `x` --> src/main.rs:17:24 | 17 | let result = x.bar(x.foo()); | - ^ value borrowed here after move | | | value moved here | = note: move occurs because `x` has type `AB`, which does not implement the `Copy` trait

我并不反对 bar 确实移动 x 的事实.我的问题是 foo 借用 x after 移动发生的声明.

I'm not disagreeing with the fact that bar indeed moves x. My issue is with the statement that foo borrows x after the move takes place.

一个简单(但丑陋)的修复:

A simple (but ugly) fix:

struct AB { a: u8, b: u8, } impl AB { fn foo(&self) -> String { String::from("foo") } fn bar(self, x: String) -> String { format!("{} - {} - {}!", x, self.a, self.b) } } fn main() { let x = AB { a: 3, b: 5 }; let y = x.foo(); let result = x.bar(y); println!("{}", result); }

将 x.foo() 的赋值分离到一个中间变量 y 编译得很好,证实了我的期望,借用确实结束了一次 foo 返回,但为什么这有效?我对评估顺序有什么不明白的地方吗?为什么我不能去掉中间的 let y ?

separating the assignment of x.foo() to an intermediate variable y compiles fine, confirming my expectation that the borrow is indeed over once foo returns, but why does this work? Is there something I don't understand about evaluation order? Why can't I get rid of the intermediate let y ?

推荐答案

求值顺序,以借用为目的,从左到右.

Evaluation order, for the purpose of borrows, is from left to right.

这意味着 bar 调用的主题,x 的移出"提及,在 x 的借用"提及之前被考虑 在 foo 调用中,因此,编译器认为该变量已被移出.

This means that the subject of the bar call, the "move-out" mention of x, is considered before the "borrow" mention of x in the foo call, and therefore, the compiler considers the variable to have been moved from.

对于外部提及是可变借用的类似情况,RFC 2025 已被接受为解决方案,但尚未实施.不幸的是,这个 RFC 似乎没有涵盖您的情况,其中外部使用是一种移动.

For the similar case where the outer mention is a mutable borrow, RFC 2025 has been accepted as a solution, but hasn't been implemented yet. Unfortunately this RFC doesn't appear to cover your case, where the outer use is a move.

更多推荐

为什么在调用一个按值获取 self 的方法时会借用一个移动的值,该方法的参数也调用一个方法?

本文发布于:2023-10-31 06:06:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545236.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法   时会   参数

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!