为什么std :: borrow :: Cow在使用正则表达式映射字符串时显然需要?

And*_*son 0 rust

我正在结构中实现代码解析器Parser.我正在公开一个pub方法lines来迭代删除注释的代码行.我想回来一个Box<Iterator>

extern crate regex; // 1.0.5

use regex::Regex;

pub struct Parser {
    code: String,
}

static comment: Regex = Regex::new(r"//.*$").unwrap();

impl Parser {
    pub fn new(code: String) -> Parser {
        Parser { code }
    }

    pub fn lines(&self) -> Box<Iterator<Item = &str>> {
        let lines = self
            .code
            .split("\n")
            .map(|line| comment.replace_all(line, ""));
        Box::new(lines)
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,编译器给出了以下错误:

error[E0271]: type mismatch resolving `<[closure@src/lib.rs:20:18: 20:54] as std::ops::FnOnce<(&str,)>>::Output == &str`
  --> src/lib.rs:21:9
   |
21 |         Box::new(lines)
   |         ^^^^^^^^^^^^^^^ expected enum `std::borrow::Cow`, found &str
   |
   = note: expected type `std::borrow::Cow<'_, str>`
              found type `&str`
   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::str::Split<'_, &str>, [closure@src/lib.rs:20:18: 20:54]>`
   = note: required for the cast to the object type `dyn std::iter::Iterator<Item=&str>`
Run Code Online (Sandbox Code Playgroud)

它想让我用std::borrow::Cow,但我无法找到任何东西Map文档提这个要求.为什么这有必要?我可以避免吗?

She*_*ter 5

强烈建议您阅读所使用的所有类型和方法的文档.例如,Regex::replace_all记录为:

pub fn replace_all<'t, R: Replacer>(
    &self, 
    text: &'t str, 
    rep: R
) -> Cow<'t, str>
//   ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

这就是它的Cow来源.

&str一旦分配了新字符串,就不可能返回s 的迭代器; 您需要选择一个新的迭代器类型.像这样的东西似乎是可能的,但由于你的代码不会因为这个生命周期问题以外的原因而编译,我无法轻易测试它.

pub fn lines<'a>(&'a self) -> Box<dyn Iterator<Item = Cow<'a, str>> + 'a>
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 感谢您对文档的建议。我是从JS过来的,而JS的对象很少有详细记录。因此,我习惯于对REPL进行自省以找出对象具有的字段。我有点把这种习惯带到了Rust中。但是现在,从现在开始,我一直在使用我的文档来开发Rust,这是一个更好的体验!谢谢! (2认同)