我最近开始尝试写一些生锈的玩具程序,我想我想要一个解析器组合器。 我天真的尝试是这样的:
enum ParseResult<T> {
Ok(T),
Error (String),
}
struct Parser<'a, I,O>{
Parse: |I|:'a ->ParseResult<O>,
}
impl<'a, I,O,J> Parser<'a, I, O>{
fn Compose<I,O,K>(self, RHS : Parser<O,K> )->Parser<I,K>{
Parser
{
Parse : |x:I|
{
let intermediate = self.Parse;
match intermediate(x){ //mismatched types: expected `I` but found `I` (expected type parameter but found type parameter)
Ok(result) =>
{
let final = RHS.Parse;
final(result) mismatched types: expected `O` but found `0` (expected type parameter but found type parameter)
}
Error(result) => Error(result)
}
}
}
}
}
我很确定错误表明我的方法存在一些根本性的错误,但我不太确定是什么。
答案 0 :(得分:2)
确实,您的计划中存在一些错误。
目前关闭是堆栈 - &#34;盒装&#34;,因此您无法从功能中返回它们,而这正是您示例中发生的事情 - 您正在存储关闭在Parser
struct。
另一个错误是通用参数的错误使用。即使没有闭包,您的方法也无法工作:I
方法上的O
和Compose
参数与impl
子句上的参数不同,即使它们具有相同的名称
intermediate
变量中。要调用存储在字段中的闭包,您需要执行以下操作:
let intermediate = (self.Parse)(x);
那就是说,几天前无箱封闭终于降落了。有了它们,你可以做你想做的事,虽然现在有些麻烦。
#![feature(unboxed_closures)]
struct Parser<I, O> {
parse: Box<FnMut<(I,), Result<O, String>>>
}
impl<I, O> Parser<I, O> {
fn compose<K>(mut self, mut rhs: Parser<O, K>) -> Parser<I, K> {
Parser {
parse: box |&mut: x: I| {
match self.parse.call_mut((x,)) {
Ok(r) => rhs.parse.call_mut((r,)),
Err(e) => Err(e)
}
}
}
}
}
这个应该工作,但现在它doesn't,对我来说这看起来像个错误:
<anon>:11:23: 11:33 error: cannot borrow data mutably in an aliasable location
<anon>:11 match self.parse.call_mut((x,)) {
^~~~~~~~~~
<anon>:12:35: 12:44 error: cannot borrow data mutably in an aliasable location
<anon>:12 Ok(result) => rhs.parse.call_mut((result,)),
^~~~~~~~~
当我用手动扩展的无盒装闭包重写这个例子时,它起作用了,所以这里确实存在一些编译器问题。无盒装的封闭是非常新的,所以这些事情并不出乎意料。我就此问题submitted an issue。