无法理解生锈的生命周期冲突
Can't understand rust lifetime conflict
我正在做一个虚拟应用程序来掌握 Rust 概念。
在执行 XML 结构时出现错误
cannot infer an appropriate lifetime for lifetime parameter in
function call due to conflicting requirements
定义是
impl<'a> XmlFile<'a>
和
pub fn get_node<'b>(self, node: &'b [u8]) -> &'b [u8]
据我所知,Rust 编译器不喜欢 return 变量可以在函数结束后被删除,如果 XML 文件在不同的时间删除(因为它们有 'a
和 'b
生命周期)。
但是,如果我输入相同的内容,则会出现错误
lifetime 'a is already in scope
,所以我没有找到解决错误的方法。
知道我错过了什么吗?我想我一定还缺乏一些 Rust 概念。
编辑:我添加导致问题的代码的部分的误解
#[allow(unused_parens)]
pub struct XmlFile<'a> {
last_open_node: &'a[u8],
last_published: String,
index_pos: u64,
content: &'a[u8],
}
impl<'a> XmlFile<'a> {
pub fn new<'b: 'a>(file: &'b [u8]) -> XmlFile<'b> {
let new_xml = XmlFile {
last_open_node: &[0: u8],
last_published: "".to_string(),
index_pos: 0,
content: file,
};
return new_xml;
}
pub fn get_node<'b: 'a>(&self, node: &'b [u8]) -> &'b [u8] {
let buf_index: u64 = 0;
let has_matched: bool = false;
self.index_pos = 0;
for c in self.content {
self.index_pos += 1;
if (c == &b'<') {
buf_index = self.index_pos;
while (c != &b' ') {
for b in node {
if b == &self.content[buf_index as usize] {
has_matched = true;
buf_index += 1
} else {
has_matched = false;
continue;
}
}
if has_matched {
while(self.content[buf_index as usize] != b'>'){
buf_index+=1;
}
let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;
}
}
}
}
return &[0 : u8];
}
pub fn get_rss_version<'b:'a>(&self) -> Result<u64 , &'static str>{
let found_slice = Self::get_node(&self, "rss".as_bytes());
if(found_slice != &[0:u8]){
let version_value = Self::get_value(found_slice);
if(version_value.is_ok()){
return Ok(version_value.unwrap()) ;
}
else{
return Err("Couldn't retrieve version from tag");
}
}
else{
println!("Couldn't find tag <rss");
return Err("Couldn't find tag <rss");
}
}
}
让我们看看你的签名 get_node
:
pub fn get_node<'b: 'a>(&mut self, node: &'b [u8]) -> &'b [u8] { ... }
以及您在此方法中实际 return 的内容:
let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;
get_node
的签名表明此方法将 returning node
的一个子片段,但你实际上 returning 一个子片段XmlFile
的 content
.
该问题的一个解决方案是了解 return 值不是 node
的一部分,而是 self.content
的一部分。因此,我们可以将签名改为:
pub fn get_node<'b>(&mut self, node: &'b [u8]) -> &'a [u8] { ... }
在这种情况下,我们甚至可以完全省略手动指定的生命周期:
pub fn get_node(&mut self, node: &[u8]) -> &[u8] { ... }
这是实际编译的 get_node
方法的清理版本:
pub fn get_node(&mut self, node: &[u8]) -> &[u8] {
let mut buf_index: u64;
let mut has_matched: bool = false;
self.index_pos = 0;
for c in self.content {
self.index_pos += 1;
if c == &b'<' {
buf_index = self.index_pos;
while c != &b' ' {
for b in node {
if b == &self.content[buf_index as usize] {
has_matched = true;
buf_index += 1
} else {
has_matched = false;
continue;
}
}
if has_matched {
while self.content[buf_index as usize] != b'>' {
buf_index += 1;
}
let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;
}
}
}
}
return &[0u8];
}
我正在做一个虚拟应用程序来掌握 Rust 概念。 在执行 XML 结构时出现错误
cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
定义是
impl<'a> XmlFile<'a>
和
pub fn get_node<'b>(self, node: &'b [u8]) -> &'b [u8]
据我所知,Rust 编译器不喜欢 return 变量可以在函数结束后被删除,如果 XML 文件在不同的时间删除(因为它们有 'a
和 'b
生命周期)。
但是,如果我输入相同的内容,则会出现错误
lifetime 'a is already in scope
,所以我没有找到解决错误的方法。
知道我错过了什么吗?我想我一定还缺乏一些 Rust 概念。
编辑:我添加导致问题的代码的部分的误解
#[allow(unused_parens)]
pub struct XmlFile<'a> {
last_open_node: &'a[u8],
last_published: String,
index_pos: u64,
content: &'a[u8],
}
impl<'a> XmlFile<'a> {
pub fn new<'b: 'a>(file: &'b [u8]) -> XmlFile<'b> {
let new_xml = XmlFile {
last_open_node: &[0: u8],
last_published: "".to_string(),
index_pos: 0,
content: file,
};
return new_xml;
}
pub fn get_node<'b: 'a>(&self, node: &'b [u8]) -> &'b [u8] {
let buf_index: u64 = 0;
let has_matched: bool = false;
self.index_pos = 0;
for c in self.content {
self.index_pos += 1;
if (c == &b'<') {
buf_index = self.index_pos;
while (c != &b' ') {
for b in node {
if b == &self.content[buf_index as usize] {
has_matched = true;
buf_index += 1
} else {
has_matched = false;
continue;
}
}
if has_matched {
while(self.content[buf_index as usize] != b'>'){
buf_index+=1;
}
let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;
}
}
}
}
return &[0 : u8];
}
pub fn get_rss_version<'b:'a>(&self) -> Result<u64 , &'static str>{
let found_slice = Self::get_node(&self, "rss".as_bytes());
if(found_slice != &[0:u8]){
let version_value = Self::get_value(found_slice);
if(version_value.is_ok()){
return Ok(version_value.unwrap()) ;
}
else{
return Err("Couldn't retrieve version from tag");
}
}
else{
println!("Couldn't find tag <rss");
return Err("Couldn't find tag <rss");
}
}
}
让我们看看你的签名 get_node
:
pub fn get_node<'b: 'a>(&mut self, node: &'b [u8]) -> &'b [u8] { ... }
以及您在此方法中实际 return 的内容:
let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;
get_node
的签名表明此方法将 returning node
的一个子片段,但你实际上 returning 一个子片段XmlFile
的 content
.
该问题的一个解决方案是了解 return 值不是 node
的一部分,而是 self.content
的一部分。因此,我们可以将签名改为:
pub fn get_node<'b>(&mut self, node: &'b [u8]) -> &'a [u8] { ... }
在这种情况下,我们甚至可以完全省略手动指定的生命周期:
pub fn get_node(&mut self, node: &[u8]) -> &[u8] { ... }
这是实际编译的 get_node
方法的清理版本:
pub fn get_node(&mut self, node: &[u8]) -> &[u8] {
let mut buf_index: u64;
let mut has_matched: bool = false;
self.index_pos = 0;
for c in self.content {
self.index_pos += 1;
if c == &b'<' {
buf_index = self.index_pos;
while c != &b' ' {
for b in node {
if b == &self.content[buf_index as usize] {
has_matched = true;
buf_index += 1
} else {
has_matched = false;
continue;
}
}
if has_matched {
while self.content[buf_index as usize] != b'>' {
buf_index += 1;
}
let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;
}
}
}
}
return &[0u8];
}