我正在 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()]
}
}
Run Code Online (Sandbox Code Playgroud)
我还没有完全理解这里的终身管理。我可以通过为属性定义具有生命周期的结构来解决问题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()]
}
}
Run Code Online (Sandbox Code Playgroud)
我收到错误:
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()]
}
}
Run Code Online (Sandbox Code Playgroud)
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.text[i..]的类型是未调整大小的类型。为了使其大小合适(因此,为了使其工作),您需要将其转换为与 相同的类型。strself.textString&strtext
如果text是,则可以通过调用切片结果String来完成;.to_string()将自动获取参考,使其合法。因此,self.text = self.text[i..].to_string();。(std::borrow::ToOwned::to_owned也可以使用并且效率会稍微高一些。)
如果text是&str,只需在切片操作前加上 前缀&,使其根据需要引用:self.text = &self.text[i..];。
对于整个一生的问题,请阅读我对/sf/answers/1720291401/的回答;它解释了你的问题等等fn next(&'a mut self)。
在我看来,您希望整个事情基于字符串切片(&str)而不是拥有的字符串(String)。前者适用于迭代器(请参阅上述答案),而后者则不适用于迭代器。
| 归档时间: |
|
| 查看次数: |
9065 次 |
| 最近记录: |