Rust 为什么在使用正则表达式映射字符串时显然需要std::borrow::Cow?
我正在Rust 为什么在使用正则表达式映射字符串时显然需要std::borrow::Cow?,rust,Rust,我正在解析器结构中实现一个代码解析器。我公开了一个pub方法lines,在删除注释的情况下迭代代码行。我想返回一个框 extern板条箱正则表达式;//1.0.5 使用regex::regex; 发布结构分析器{ 代码:String, } 静态注释:Regex=Regex::new(r”//*$”).unwrap(); impl解析器{ pub fn new(代码:String)->解析器{ 解析器{code} } 发布fn行(&self)->框{ 让线=自我 .代码 .split(“\n”)
解析器
结构中实现一个代码解析器。我公开了一个pub方法lines
,在删除注释的情况下迭代代码行。我想返回一个框
extern板条箱正则表达式;//1.0.5
使用regex::regex;
发布结构分析器{
代码:String,
}
静态注释:Regex=Regex::new(r”//*$”).unwrap();
impl解析器{
pub fn new(代码:String)->解析器{
解析器{code}
}
发布fn行(&self)->框{
让线=自我
.代码
.split(“\n”)
.map(|行|注释。替换|所有(行“”);
框::新(行)
}
}
但是,编译器给出了以下错误:
error[E0271]:类型不匹配解析`::Output==&str`
-->src/lib.rs:21:9
|
21 |框::新(行)
|^^^^^^^^^^^^^^^^^^^^^^^^^预期枚举'std::borrow::Cow',found&str
|
=注意:预期类型为'std::borrow::Cow[closure@src/图书馆:20:18:20:54]>`
=注意:强制转换到对象类型'dyn std::iter::Iterator'时需要`
它想让我使用
std::borrow::Cow
,但我在提到这个要求时找不到任何东西。为什么这是必要的?我可以避免吗?强烈建议您阅读您正在使用的所有类型和方法的文档。例如,记录为:
pub fn replace_all<'t, R: Replacer>(
&self,
text: &'t str,
rep: R
) -> Cow<'t, str>
// ^^^^^^^^^^^^
另见:
pub fn replace_all<'t, R: Replacer>(
&self,
text: &'t str,
rep: R
) -> Cow<'t, str>
// ^^^^^^^^^^^^
另见:
&str的迭代器:
extern crate regex; // 1.0.5
use regex::Regex;
use std::borrow::Cow;
pub struct Parser {
code: String,
}
impl Parser {
pub fn new(code: String) -> Parser {
Parser { code }
}
pub fn lines<'a>(&'a self, comment: Regex) -> Box<Iterator<Item = &'a str> + 'a> {
let lines = self
.code
.split("\n")
.map(move |line| comment.replace_all(line, ""))
.map(|cow| match cow {
Cow::Borrowed(sref) => sref,
Cow::Owned(_) => panic!("I hope never to be here"),
});
Box::new(lines)
}
}
fn main() {
let comment: Regex = Regex::new(r"//.*$").unwrap();
let p = Parser::new("hello\nworld".to_string());
for item in p.lines(comment) {
println!("{:?}", item);
}
}
正如你已经发现的,来自
在您的情况下,有一种非常危险且令人沮丧的方法来获取&str的迭代器:
extern crate regex; // 1.0.5
use regex::Regex;
use std::borrow::Cow;
pub struct Parser {
code: String,
}
impl Parser {
pub fn new(code: String) -> Parser {
Parser { code }
}
pub fn lines<'a>(&'a self, comment: Regex) -> Box<Iterator<Item = &'a str> + 'a> {
let lines = self
.code
.split("\n")
.map(move |line| comment.replace_all(line, ""))
.map(|cow| match cow {
Cow::Borrowed(sref) => sref,
Cow::Owned(_) => panic!("I hope never to be here"),
});
Box::new(lines)
}
}
fn main() {
let comment: Regex = Regex::new(r"//.*$").unwrap();
let p = Parser::new("hello\nworld".to_string());
for item in p.lines(comment) {
println!("{:?}", item);
}
}
这是对我来说最好的解决办法
replace_all
不是这个用例的好方法。我只想删除评论。我从不需要在字符串中插入任何内容。如果是这样的话,我应该能够处理字符串切片。无需使用replace\u all
引入的Cow
类型。以下是我是如何做到的
impl Parser {
pub fn lines<'a>(&'a self) -> Box<dyn Iterator<Item = &'a str> + 'a> {
let lines = self.code
.lines()
.map(|line| { line.split("//").next().unwrap() })
.map(|line| line.trim())
.filter(|line| line.len() > 0);
Box::new(lines)
}
}
impl解析器{
酒吧fn线盒{
让line=self.code
.行()
.map(| line |{line.split(“/”).next().unwrap()})
.map(| line | line.trim())
.filter(| line | line.len()>0);
框::新(行)
}
}
这是针对我的案例的最佳解决方案
replace_all
不是这个用例的好方法。我只想删除评论。我从不需要在字符串中插入任何内容。如果是这样的话,我应该能够处理字符串切片。无需使用replace\u all
引入的Cow
类型。以下是我是如何做到的
impl Parser {
pub fn lines<'a>(&'a self) -> Box<dyn Iterator<Item = &'a str> + 'a> {
let lines = self.code
.lines()
.map(|line| { line.split("//").next().unwrap() })
.map(|line| line.trim())
.filter(|line| line.len() > 0);
Box::new(lines)
}
}
impl解析器{
酒吧fn线盒{
让line=self.code
.行()
.map(| line |{line.split(“/”).next().unwrap()})
.map(| line | line.trim())
.filter(| line | line.len()>0);
框::新(行)
}
}
Idiomatic Rust使用snake\u case
表示变量、方法、宏和字段<对于类型,代码>大写
;对于静力学和常数,SNAKE\u案例
。请改为使用静态注释
。惯用的Rust使用snake\u case
表示变量、方法、宏和字段<对于类型,代码>大写
;对于静力学和常数,SNAKE\u案例
。请改为使用静态注释
。坦率地说,这是一个糟糕的建议。如果永远不需要运行replace\u all
调用(因此永远不需要返回Cow::Owned
),那么它就不应该在那里。想必OP确实需要出于某种原因删除注释,因此这总是会引起恐慌。我也不同意返回String
s通常是“更好”的说法;现在您必须为每一行重新分配,这似乎是对性能的极大浪费。事实上,我只需要删除注释。不需要复印件。我认为replace\u all
对我来说是一个糟糕的方法选择。我发布了一个更好的方法的答案。坦率地说,这是一个糟糕的建议。如果永远不需要运行replace\u all
调用(因此永远不需要返回Cow::Owned
),那么它就不应该在那里。想必OP确实需要出于某种原因删除注释,因此这总是会引起恐慌。我也不同意返回String
s通常是“更好”的说法;现在您必须为每一行重新分配,这似乎是对性能的极大浪费。事实上,我只需要删除注释。不需要复印件。我认为replace\u all
对我来说是一个糟糕的方法选择。我发布了一个更好的方法的答案。谢谢你关于文档的建议。我来自JS,它的对象很少有很好的文档记录。所以我习惯于在REPL中进行内省,以找出对象具有哪些字段。我把这个习惯带到了铁锈里。但现在,从现在起,我一直在用手头的文档开发我的锈迹,这是一个更好的体验!谢谢感谢您对文档的推荐。我来自JS,它的对象很少有很好的文档记录。所以我习惯于在REPL中进行内省,以找出对象具有哪些字段。我把这个习惯带到了铁锈里。但现在,从现在起,我一直在用手头的文档开发我的锈迹,这是一个更好的体验!谢谢