为啥 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) -> crate::Result<String>
。我认为Result<>
中的String
意味着返回的值拥有文本或其副本的所有权。
@Jerry self
,这意味着它需要self: Self
,也就是按值获取主题。 &self
将是 self: &Self
也就是通过共享引用获取主题,&mut self
将是 self: &mut Self
也就是通过唯一引用获取主题。以上是关于为啥 println!(foo.bar()?) 移动 foo?的主要内容,如果未能解决你的问题,请参考以下文章