无法移出借用的内容/无法移出共享参考
Cannot move out of borrowed content / cannot move out of behind a shared reference
我不明白错误 cannot move out of borrowed content
。收到过很多次,一直都解决了,但是一直不明白为什么。
例如:
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
产生错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ cannot move out of borrowed content
在较新版本的 Rust 中,错误是
error[E0507]: cannot move out of `*line` which is behind a shared reference
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait
我通过克隆解决了它 line
:
for current_char in line.clone().into_bytes().iter() {
即使阅读了其他帖子,我仍然不明白错误:
这种错误的根源是什么?
让我们看看into_bytes
的签名:
fn into_bytes(self) -> Vec<u8>
这需要 self
,而不是对自身的引用 (&self
)。这意味着 self
将被 消耗掉 并且在调用后将不可用。取而代之的是 Vec<u8>
。前缀 into_
是表示此类方法的常用方式。
我不知道你的 iter()
方法 returns 到底是什么,但我的猜测是它是 &String
上的迭代器,也就是说,它 returns 引用到 String
但不会让您拥有它们。这意味着您不能调用使用值 的方法。
如您所见,一种解决方案是使用 clone
。这会创建一个您 拥有 并可以调用 into_bytes
的重复对象。正如其他评论者所提到的,您还可以使用 as_bytes
,它需要 &self
,因此它可以在借来的值上工作。您应该使用哪一个取决于您使用指针的最终目标。
从更大的角度来看,这一切都与所有权的概念有关。某些操作依赖于拥有该项目,而其他操作可以借用该对象(可能是可变的)。引用 (&foo
) 不授予所有权,它只是借用。
Why is it interesting to use self
instead of &self
in a function's arguments?
转让所有权通常是一个有用的概念 - 当我完成某件事时,其他人可能会拥有它。在 Rust 中,这是一种提高效率的方法。我可以避免分配一个副本,给你一个副本,然后扔掉我的副本。所有权也是最宽松的状态;如果我拥有一件物品,我可以随心所欲地使用它。
这是我创建的用于测试的代码:
struct IteratorOfStringReference<'a>(&'a String);
impl<'a> Iterator for IteratorOfStringReference<'a> {
type Item = &'a String;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
struct FileLikeThing {
string: String,
}
impl FileLikeThing {
fn iter(&self) -> IteratorOfStringReference {
IteratorOfStringReference(&self.string)
}
}
struct Dummy {
xslg_file: FileLikeThing,
buffer: String,
}
impl Dummy {
fn dummy(&mut self) {
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
}
}
fn main() {}
我不明白错误 cannot move out of borrowed content
。收到过很多次,一直都解决了,但是一直不明白为什么。
例如:
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
产生错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ cannot move out of borrowed content
在较新版本的 Rust 中,错误是
error[E0507]: cannot move out of `*line` which is behind a shared reference
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait
我通过克隆解决了它 line
:
for current_char in line.clone().into_bytes().iter() {
即使阅读了其他帖子,我仍然不明白错误:
这种错误的根源是什么?
让我们看看into_bytes
的签名:
fn into_bytes(self) -> Vec<u8>
这需要 self
,而不是对自身的引用 (&self
)。这意味着 self
将被 消耗掉 并且在调用后将不可用。取而代之的是 Vec<u8>
。前缀 into_
是表示此类方法的常用方式。
我不知道你的 iter()
方法 returns 到底是什么,但我的猜测是它是 &String
上的迭代器,也就是说,它 returns 引用到 String
但不会让您拥有它们。这意味着您不能调用使用值 的方法。
如您所见,一种解决方案是使用 clone
。这会创建一个您 拥有 并可以调用 into_bytes
的重复对象。正如其他评论者所提到的,您还可以使用 as_bytes
,它需要 &self
,因此它可以在借来的值上工作。您应该使用哪一个取决于您使用指针的最终目标。
从更大的角度来看,这一切都与所有权的概念有关。某些操作依赖于拥有该项目,而其他操作可以借用该对象(可能是可变的)。引用 (&foo
) 不授予所有权,它只是借用。
Why is it interesting to use
self
instead of&self
in a function's arguments?
转让所有权通常是一个有用的概念 - 当我完成某件事时,其他人可能会拥有它。在 Rust 中,这是一种提高效率的方法。我可以避免分配一个副本,给你一个副本,然后扔掉我的副本。所有权也是最宽松的状态;如果我拥有一件物品,我可以随心所欲地使用它。
这是我创建的用于测试的代码:
struct IteratorOfStringReference<'a>(&'a String);
impl<'a> Iterator for IteratorOfStringReference<'a> {
type Item = &'a String;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
struct FileLikeThing {
string: String,
}
impl FileLikeThing {
fn iter(&self) -> IteratorOfStringReference {
IteratorOfStringReference(&self.string)
}
}
struct Dummy {
xslg_file: FileLikeThing,
buffer: String,
}
impl Dummy {
fn dummy(&mut self) {
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
}
}
fn main() {}