我正在Rust中编写HTTP解析器。所有输入都是ASCII,所以我只使用&[u8]
来迭代字节。
#[derive(Debug)]
pub enum ParseError {
Method,
OutOfBound,
}
struct Bytes<'src> {
source: &'src [u8],
i: usize, //current position in the source
}
impl<'src> Bytes<'src> {
fn next(&mut self) -> Option<u8> {
if self.source.len() > self.i + 1 {
self.i += 1;
Some(self.source[self.i - 1])
} else {
None
}
}
fn until(&mut self, stop: u8) -> Result<&[u8], ParseError> {
let start = self.i;
while let Some(ch) = self.next() {
if ch == stop {
return Ok(&self.source[start..self.i - 1]);
}
}
Err(ParseError::OutOfBound)
}
}
此功能:
use std::str;
fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
let until = try!(bytes.until(b' '));
unsafe { Ok(str::from_utf8_unchecked(until)) }
}
产生错误:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:37:28
|
37 | let until = try!(bytes.until(b' '));
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 36:1...
--> src/main.rs:36:1
|
36 | / fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
37 | | let until = try!(bytes.until(b' '));
38 | | unsafe { Ok(str::from_utf8_unchecked(until)) }
39 | | }
| |_^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:37:22
|
37 | let until = try!(bytes.until(b' '));
| ^^^^^
note: but, the lifetime must be valid for the lifetime 'str as defined on the function body at 36:1...
--> src/main.rs:36:1
|
36 | / fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
37 | | let until = try!(bytes.until(b' '));
38 | | unsafe { Ok(str::from_utf8_unchecked(until)) }
39 | | }
| |_^
note: ...so that expression is assignable (expected std::result::Result<&'str str, _>, found std::result::Result<&str, _>)
--> src/main.rs:38:14
|
38 | unsafe { Ok(str::from_utf8_unchecked(until)) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
这很奇怪,因为'until'引用了一个函数参数,所以我认为这不应该是一个问题。
更奇怪的是,当我直接索引字节时,它会编译。
fn uri<'str>(bytes: &mut Bytes<'str>) -> Result<&'str str, ParseError> {
unsafe { Ok(str::from_utf8_unchecked(&bytes.source[20..30])) }
}
为什么?