Eu não entendo o erro cannot move out of borrowed content
. Eu o recebi muitas vezes e sempre o resolvi, mas nunca entendi o porquê.
Por exemplo:
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);
}
produz o erro:
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
Nas versões mais recentes do Rust, o erro é
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
Eu o resolvi clonando line
:
for current_char in line.clone().into_bytes().iter() {
Não entendo o erro mesmo depois de ler outras postagens como:
- Não é possível emprestar o arquivo do & mut self (mensagem de erro: não é possível sair do conteúdo emprestado)
- Alterando um nó em uma árvore no Rust
Qual é a origem desse tipo de erro?
.bytes()
método.).as_bytes()
as_bytes()
sem clonagem. Mas ainda não entendo o porquê?String
obtém obytes
método destr
.Respostas:
Vejamos a assinatura para
into_bytes
:Isso leva
self
, não uma referência a self (&self
). Isso significa queself
será consumido e não estará disponível após a chamada. Em seu lugar, você recebe umVec<u8>
. O prefixointo_
é uma maneira comum de denotar métodos como este.Não sei exatamente o que seu
iter()
método retorna, mas meu palpite é que é um iterador encerrado&String
, ou seja, retorna referências a um,String
mas não lhe dá a propriedade. Isso significa que você não pode chamar um método que consome o valor .Como você encontrou, uma solução é usar
clone
. Isso cria um objeto duplicado que você faz próprios, e pode chamarinto_bytes
diante. Como outros comentadores mencionam, você também pode usar asas_bytes
tomadas&self
, para que funcionem com um valor emprestado. Qual deles você deve usar depende do seu objetivo final para o que você faz com o ponteiro.No quadro geral, tudo isso tem a ver com a noção de propriedade . Certas operações dependem da propriedade do item, e outras operações podem evitar o empréstimo do objeto (talvez mutuamente). Uma referência (
&foo
) não concede propriedade, é apenas um empréstimo.Transferir propriedade é um conceito útil em geral - quando eu termino alguma coisa, alguém pode tê-la. No Rust, é uma maneira de ser mais eficiente. Eu posso evitar alocar uma cópia, fornecendo uma cópia e depois jogando fora a minha cópia. A propriedade também é o estado mais permissivo; se eu possuo um objeto, posso fazê-lo como desejar.
Aqui está o código que eu criei para testar:
fonte