【发布时间】:2014-03-22 22:27:37
【问题描述】:
我目前正在尝试在 Rust 中实现一个简单的 Parser-Combinator 库。为此,我想要一个通用的 map 函数来转换解析器的结果。
问题是我不知道如何复制一个包含闭包的结构。一个示例是以下示例中的 Map 结构。它有一个mapFunction 字段存储一个函数,该函数接收前一个解析器的结果并返回一个新结果。 Map 本身就是一个解析器,可以与其他解析器进一步结合。
但是,对于要组合的解析器,我需要它们是可复制的(具有 Clone 特征绑定),但我如何为 Map 提供这个?
示例:(仅伪代码,很可能无法编译)
trait Parser<A> { // Cannot have the ": Clone" bound because of `Map`.
// Every parser needs to have a `run` function that takes the input as argument
// and optionally produces a result and the remaining input.
fn run(&self, input: ~str) -> Option<(A, ~str)>
}
struct Char {
chr: char
}
impl Parser<char> for Char {
// The char parser returns Some(char) if the first
fn run(&self, input: ~str) -> Option<(char, ~str)> {
if input.len() > 0 && input[0] == self.chr {
Some((self.chr, input.slice(1, input.len())))
} else {
None
}
}
}
struct Map<'a, A, B, PA> {
parser: PA,
mapFunction: 'a |result: A| -> B,
}
impl<'a, A, B, PA: Parser<A>> Parser<B> for Map<'a, A, B, PA> {
fn run(&self, input: ~str) -> Option<(B, ~str)> {
...
}
}
fn main() {
let parser = Char{ chr: 'a' };
let result = parser.run(~"abc");
// let mapParser = parser.map(|c: char| atoi(c));
assert!(result == Some('a'));
}
【问题讨论】:
-
闭包不能被克隆。当您使用闭包时,我看不到任何摆脱困境的方法;看看你是否可以使用其他东西,例如裸函数。
-
使用裸函数是我目前的解决方法。从客户的角度来看,我只是觉得它很难看。不过,感谢您的回答。