&str 字符串和生命周期

&str String and lifetime

我正在用 Rust 开发一个小型词法分析器。我想到了将词法分析阶段放入 Iterator 特征的实现中。

struct Lexer {
    text: String
}

impl Iterator for Lexer {
    ...
    fn next(&mut self) -> Option<LexItem>{
        ....
        // slicing issue
        self.text = self.text[i .. self.text.len()]

    }
}

我还没有完全理解这里的生命周期管理。通过为 text 属性定义具有生命周期的结构,我会很好,这将(可能)使子切片更容易。然而,我未能在我的代码中加入这样的生命周期。另一方面,我很难再次将切片 self.text[i .. .....] 转换为 String(不知道是否可能)。

我尝试了什么:

我尝试了以下修改:

struct Lexer<'a> {
    text: &'a str
}

impl<'a> Iterator for Lexer<'a> {
    ...
    fn next(&'a mut self) -> Option<LexItem>{
        ....
        // slicing issue
        self.text = self.text[i .. self.text.len()]

    }
}

我收到错误:

src/lexer.rs:64:5: 81:6 错误:方法 `next` 的特征类型不兼容:预期绑定生命周期参数,找到具体生命周期 [E0053]

我试过的其他实现方式

impl<'a> Iterator for Lexer<'a> {
    ...
    fn next<'b>(&'b mut self) -> Option<LexItem>{
        ....
        // slicing issue
        self.text = self.text[i .. self.text.len()]

    }
}
src/lexer.rs:66:21: 66:52 错误:类型不匹配:
 预期`&'a str`,
    找到`str`
(预期 &-ptr,
    找到 str) [E0308]
src/lexer.rs:66 self.text = self.text[i .. self.text.len()];
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我认为这样的事情应该可行,因为我只处理子切片。

(顺便说一句:foo[i..foo.len()] 应始终等同于 foo[i..]。)

如果 self.textString&str 类型,self.text[i..] 的类型是未调整大小的类型 str。为了调整它的大小(因此,为了让它工作),你需要把它变成与 text.

相同的类型

如果textString,这可以通过对切片结果调用.to_string()来完成;将自动引用,使其合法。因此,self.text = self.text[i..].to_string();。 (也可以使用std::borrow::ToOwned::to_owned,效率会稍微高一些。)

如果text&str,只需在切片操作前加上&前缀,使其根据需要获取引用:self.text = &self.text[i..];.

一辈子的事,请看我对的回答;它解释了 fn next(&'a mut self) 等问题。

在我看来,您希望整个事情都基于字符串切片 (&str) 而不是拥有的字符串 (String)。前者适用于迭代器(参见上述答案),而后者则不行。