오류를 이해하지 못합니다 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
)에 대한 참조가 아니라을 사용 합니다. 의미 self
한다 소비 하고 통화 후 사용할 수 없습니다. 그 자리에서 Vec<u8>
. 접두사 into_
는 이와 같은 방법을 나타내는 일반적인 방법입니다.
나는 당신의 iter()
메소드가 무엇을 반환 하는지 정확히 알지 못합니다 . 그러나 제 생각에는 그것이 반복 자라는 &String
것입니다. 즉, 그것은 a에 대한 참조를 반환 String
하지만 당신에게 소유권을주지 않습니다. 즉 , 값을 사용하는 메서드를 호출 할 수 없습니다 .
아시다시피 한 가지 해결책은 clone
. 이렇게하면 자신 이 소유하고 호출 할 수 있는 중복 개체가 만들어집니다 into_bytes
. 다른 댓글 작성자가 언급했듯이 as_bytes
which take 를 사용할 수도 &self
있으므로 차용 한 값에서 작동합니다. 어떤 것을 사용해야하는지는 포인터로 무엇을하는지에 대한 최종 목표에 따라 다릅니다.
큰 그림에서이 모든 것은 소유권 개념과 관련이 있습니다. 특정 작업은 항목 소유에 따라 다르며 다른 작업은 객체를 차용하여 벗어날 수 있습니다 (아마도 변경 가능). 참조 ( &foo
)는 소유권을 부여하는 것이 아니라 차용 일뿐입니다.
함수의 인수
self
대신 사용 하는 것이 흥미로운 이유는 무엇&self
입니까?
소유권 이전은 일반적으로 유용한 개념입니다. 내가 어떤 일을 마치면 다른 사람이 그것을 가질 수 있습니다. 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() {}