【问题标题】:Can't understand rust lifetime conflict无法理解生锈寿命冲突
【发布时间】:2021-07-28 21:04:39
【问题描述】:

我正在制作一个虚拟应用程序来掌握 Rust 概念。 在做一个 XML 结构时,我得到了错误

无法为生命周期参数推断适当的生命周期 由于需求冲突导致的函数调用

定义是

impl<'a> XmlFile<'a>

pub fn get_node<'b>(self, node: &'b [u8]) -> &'b [u8] 

据我了解,Rust 编译器不喜欢在函数结束后删除返回变量,如果 XML 文件在不同的时间删除(因为它们有 'a'b 生命周期)。 但是如果我把同样的,我得到错误

lifetime 'a 已经在范围内

,所以我看不到解决错误的方法。

知道我错过了什么吗?我想我一定还是缺少一些 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");
        }
    }
}

【问题讨论】:

  • 你如何使用这个?请创建一个MCVE 并将其编辑到您的问题中。
  • 这个错误不仅仅来自定义,它来自与这些定义冲突的用途。请包含导致错误的代码。
  • 请注意get_node() 拥有self 的所有权,如果此方法是“getter”,这可能不是您想要的,因为XmlFile 将在get_node() 返回时被丢弃。您的意思可能是&amp;self,但正如其他 cmets 所说,此处需要详细信息。

标签: rust lifetime


【解决方案1】:

让我们看看你对get_node的签名:

pub fn get_node<'b: 'a>(&mut self, node: &'b [u8]) -> &'b [u8] { ... }

以及您在此方法中实际返回的内容:

let r = &self.content[self.index_pos as usize..buf_index as usize];
return r;

get_node 的签名表明此方法将返回 node 的子切片,但您实际上返回的是 XmlFilecontent 的子切片。

该问题的一个解决方案是了解返回值不是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];
}

【讨论】:

  • 感谢@flumpb ,仍然无法理解为什么它要求一生,但您的解决方案有效。
猜你喜欢
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-07
相关资源
最近更新 更多