빌린 콘텐츠 밖으로 이동할 수 없음 / 공유 참조 뒤로 이동할 수 없음
오류를 이해하지 못합니다 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()
메소드가 무엇을 반환 하는지 정확히 알지 못하지만, 내 생각에 그것은 iterator 반복자입니다 &String
. 즉,에 대한 참조를 반환 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() {}
'Programming' 카테고리의 다른 글
C ++ 객체를 자체 생성자에 전달하는 것이 합법적입니까? (0) | 2020.08.04 |
---|---|
프로젝트에서 * plugins *에 대한 Maven 종속성 트리를 어떻게 표시 할 수 있습니까? (0) | 2020.08.04 |
SignalR과 RESTful API를 모두 통합 할 수 있습니까? (0) | 2020.08.04 |
히스토리를 유지하면서 git 저장소에서 새 저장소로 단일 디렉토리를 이동하려면 어떻게해야합니까? (0) | 2020.08.04 |
종료 / 중지 될 때 중요한 변경 위치 API에 대한 동작? (0) | 2020.08.04 |