대여 한 콘텐츠 밖으로 이동할 수 없거나 공유 참조 뒤로 이동할 수 없습니다.


127

오류를 이해하지 못합니다 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() {

다음과 같은 다른 게시물을 읽은 후에도 오류를 이해하지 못합니다.

이런 종류의 오류의 원인은 무엇입니까?


1
이와 같은 질문을 보셨습니까 ? (Btw, 현이 .bytes()방법을 제공합니다 .)
huon

예, 조사했지만 이해하지 못했습니다. (그리고 내 문자열은 std :: string :: String입니다. 설명서에 따르면 .bytes () 메서드가 없습니다
Peekmo

4
그것은라고.as_bytes()
bluss

사실, 감사합니다 as_bytes(). 복제없이 작동합니다 . 하지만 여전히 왜 그런지 이해가 안 돼요?
Peekmo

String에서 bytes메서드를 가져옵니다 str.
huon

답변:


108

다음에 대한 서명을 살펴 보겠습니다 into_bytes.

fn into_bytes(self) -> Vec<u8>

이것은 selfself ( &self)에 대한 참조가 아니라을 사용 합니다. 의미 self한다 소비 하고 통화 후 사용할 수 없습니다. 그 자리에서 Vec<u8>. 접두사 into_는 이와 같은 방법을 나타내는 일반적인 방법입니다.

나는 당신의 iter()메소드가 무엇을 반환 하는지 정확히 알지 못합니다 . 그러나 제 생각에는 그것이 반복 자라는 &String것입니다. 즉, 그것은 a에 대한 참조를 반환 String하지만 당신에게 소유권을주지 않습니다. 즉 , 값을 사용하는 메서드를 호출수 없습니다 .

아시다시피 한 가지 해결책은 clone. 이렇게하면 자신 소유하고 호출 할 수 있는 중복 개체가 만들어집니다 into_bytes. 다른 댓글 작성자가 언급했듯이 as_byteswhich 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() {}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.