如何解决无法移出可变引用后面的***
我有下一个代码:
struct Tokenizer {
reader: BufReader<File>,buf: Vec<u8>,token: String
}
impl Tokenizer {
fn new(path: &PathBuf) -> Tokenizer {
let file = File::open(path).expect("Unable to open file!");
Tokenizer {
reader: BufReader::new(file),buf: Vec::<u8>::new(),token: String::new()
}
}
fn next(&mut self) -> bool {
if self.buf.len() == 0 {
if self.reader.read_until(b'\n',&mut self.buf)
.expect("Unable to read file") == 0 {
return false;
}
}
let s = String::from_utf8(self.buf).expect("Unable to read file");
let mut start: i8 = -1;
let mut end: i8 = -1;
for (i,c) in s.char_indices() {
if start == -1 {
if !c.is_whitespace() {
start = i as i8;
}
} else {
if c.is_whitespace() {
end = i as i8;
}
}
}
self.token = s.chars().skip(start as usize).take((end - start) as usize).collect();
self.buf = s.into_bytes();
self.buf.clear();
return true;
}
}
但是由于错误,它不起作用:
error[E0507]: cannot move out of `self.buf` which is behind a mutable reference
--> src\parser.rs:28:35
|
28 | let s = String::from_utf8(self.buf).expect("Unable to read file");
| ^^^^^^^^ move occurs because `self.buf` has type `std::vec::Vec<u8>`,which does not implement the `Copy` trait
我读过类似的问题,建议使用swap
,但我不知道它如何对我有所帮助。如何解决此错误以及为什么不编译?
解决方法
String::from_utf8
按值获取其参数,这意味着它不仅仅使用被赋予其消费的vec。
但是在这里它不能消耗输入:因为self
只是可变借用self.buf
最多是可变借用(又名&mut Vec<u8>
),因此签名不匹配。这是因为String::from_utf8
将检查输入是否有效,然后只是将其重新解释为为有效字符串,从而避免了新分配。
有两种简单的方法可以解决此问题,我可以在这里看到:
最简单的方法是使用将引用作为输入的函数,例如str::from_utf8
,它将在内部分配一个新的String以便返回数据,因此效率较低,但更方便。
备选方案以及您得到的swap
建议是将数据移出借用项:如果您有可变借项,则不能消费 {{1 }},但您可以用新的(自有的)缓冲区替换。
self.buf
执行此操作并返回旧值,因此您可以将swap
的当前内容交换为全新的(空)向量,然后退出向量以前称为self.buf
,现在归您所有(而不是self.buf
),因此可以消费。
在这里的样子是:
self
,
由于String::from_utf8
试图获取其参数的所有权,因此出现此错误。在您的情况下,它是&mut self
的属性,已被引用(您打算将来使用此结构,而不是使用它)。
简便的解决方案是使用其他具有参考意义的功能:
fn next(&mut self) -> bool {
...
let s = String::from_utf8_lossy(&self.buf[..]);
...
}
并在您要清理self.buf = s.into_bytes();
的行时将其删除。1.在下一行清洁它; 2.尚未使用,但已引用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。