为啥 println!(foo.bar()?) 移动 foo?

Posted

技术标签:

【中文标题】为啥 println!(foo.bar()?) 移动 foo?【英文标题】:Why does println!(foo.bar()?) move foo?为什么 println!(foo.bar()?) 移动 foo? 【发布时间】:2021-06-01 23:30:15 【问题描述】:

bar()的定义:

pub fn bar(self) -> Result<String>

编译器给我一个错误:

println!("", foo.bar()?);
let deserialized = serde_json::from_str(&foo.bar()?)?; // Use of 'foo' after move

为什么println 会移动foo?当我将另一个变量绑定到foo.bar() 时,编译器就可以了。

编辑:这基本上就是我所拥有的

let res = reqwest::blocking::get(request_path)?;
println!("", res.text()?);
                   ------ `res` moved due to this method call
let deserialized = serde_json::from_str(&res.text()?)?;
                                         ^^^ value used here after move

【问题讨论】:

在我看来这是对bar() 的第一次调用,它取得了foo 的所有权并且没有归还它,与println! 无关。有效的完整代码是什么? 很难回答您的问题,因为它不包含minimal reproducible example。我们无法分辨代码中存在哪些 crate(及其版本)、类型、特征、字段等。如果您尝试在Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在全新的 Cargo 项目中,然后在edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢! 请edit 您的问题并粘贴您所得到的准确和完整的错误——这将帮助我们了解问题所在,以便我们能够提供最好的帮助。有时试图解释错误消息很棘手,实际上错误消息的不同部分很重要。请使用直接运行编译器的消息,而不是 IDE 生成的消息,它可能会尝试为您解释错误。 【参考方案1】:

是什么让您认为 println 正在采取行动? bar 明确表示它在移动;你会得到同样的错误:

let x = foo.bar()?;
let y = foo.bar()?;  // Error, foo has been moved.

当我将另一个变量绑定到 foo.bar() 时,编译器就可以了。

因为现在您不再尝试使用foo。相反,您可以多次重复使用调用的返回值,这很好(也就是说,直到 it 被移动!)。

【讨论】:

"bar 明确指出它移动" 函数签名的哪一部分告诉你这个?我添加了我正在做的事情的 sn-p,res.text() 的签名是pub fn text(self) -&gt; crate::Result&lt;String&gt;。我认为Result&lt;&gt; 中的String 意味着返回的值拥有文本或其副本的所有权。 @Jerry self,这意味着它需要self: Self,也就是按值获取主题。 &amp;self 将是 self: &amp;Self 也就是通过共享引用获取主题,&amp;mut self 将是 self: &amp;mut Self 也就是通过唯一引用获取主题。

以上是关于为啥 println!(foo.bar()?) 移动 foo?的主要内容,如果未能解决你的问题,请参考以下文章

vim 中的字符串替换:为啥 %s/foo/bar 有效? [复制]

jquery 冒号转义 为啥双斜杠

为啥这个方法调用不明确?

为啥我不能内联创建新的 Java 数组? [复制]

为啥我不能内联创建新的 Java 数组? [复制]

Python - 为啥通过值传递的 ndarray 在函数外部发生变化? [复制]