war*_*ock 0 loops rust borrow-checker
是否可以编写一个函数,BufRead::fill_buf直到io::ErrorKind::Interrupted使用不安全方法调用该函数直到不再发生?
使用不安全的代码,它是:
use std::{
io::{self, BufRead},
slice,
};
fn fill_buf_and_ignore_interrupts(reader: &mut impl BufRead) -> io::Result<&[u8]> {
let (buf_ptr, buf_len) = loop {
match reader.fill_buf() {
Ok(buf) => (buf.as_ptr(), buf.len()),
Err(e) => {
if e.kind() != io::ErrorKind::Interrupted {
return Err(e);
}
}
}
};
Ok(unsafe { slice::from_raw_parts(buf_ptr, buf_len) })
}
Run Code Online (Sandbox Code Playgroud)
如果尝试使用return或break Ok(buf),则从借阅检查器收到错误消息:
error[E0499]: cannot borrow `*reader` as mutable more than once at a time
--> src/lib.rs:8:15
|
6 | fn fill_buf_and_ignore_interrupts(reader: &mut impl BufRead) -> io::Result<&[u8]> {
| - let's call the lifetime of this reference `'1`
7 | let (buf_ptr, buf_len) = loop {
8 | match reader.fill_buf() {
| ^^^^^^ mutable borrow starts here in previous iteration of loop
9 | Ok(buf) => return Ok(buf),
| ------- returning this value requires that `*reader` is borrowed for `'1`
Run Code Online (Sandbox Code Playgroud)
我试图用递归替换循环,但错误仍然存在。我也尝试过使用#![feature(nll)],但是它也不起作用。
您不能,并且也不想出于以下突出显示的原因(它们与参考return或无关unsafe)。fill_buf由于文档中的一项重要警告,因此无法按您认为的方式工作:
返回内部缓冲区的内容,如果内部缓冲区为空,则从内部读取器中填充更多数据。
换句话说,在随后的通话fill_buf,而不consume会,如果性状正常执行,遵循在文档规定的合同无操作。因此,如果您在任何需要调用的地方忘记了该要求,则一无所有就会充满风险fill_buf。
两种解决方案:
BufReader在不少其他语言一样),只是BufRead::read_to_end(),BufRead::read_line()或BufRead::read_until()。如果可以识别定界符,read_until则可以轻松地将其加工成可迭代的结构Pattern或单个字节(BufRead覆盖)。作为一个简短的摘要,请fill_buf不要执行您认为会做的事情,并且在不消耗缓冲区内部状态的情况下,无需多次调用它。如果您不尝试执行此操作,则的较低级别方法BufRead不是该工作的工具。
| 归档时间: |
|
| 查看次数: |
499 次 |
| 最近记录: |