我有一个枚举:
enum Expr {
Lit(u32),
Var(Id),
Ass(Id, u32),
Add(u32, u32),
Sub(u32, u32),
Mul(u32, u32),
}
我正在尝试实现一种方法:
impl Expr {
fn eval(&self, env: &mut Env) -> Result<u32, String> {
use Expr::*;
match *self {
Lit(l) => Ok(l),
Var(id) => env.lookup(&id).ok_or_else(|| format!("undefined var {:?}", id)),
Ass(id, v) => {
env.assign(id, v);
Ok(v)
}
Add(f, s) => Ok(f + s),
Sub(f, s) => Ok(f - s),
Mul(f, s) => Ok(f * s),
}
}
}
但出现以下错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:25:15
|
25 | match *self {
| ^^^^^ cannot move out of borrowed content
26 | Lit(l) => Ok(l),
27 | Var(id) => env.lookup(&id).ok_or_else(|| format!("undefined var {:?}", id)),
| -- hint: to prevent move, use `ref id` or `ref mut id`
28 | Ass(id, v) => {
| -- ...and here (use `ref id` or `ref mut id`)
没有星星,我也会得到一个错误:
error[E0308]: mismatched types
--> src/main.rs:25:17
|
25 | Lit(l) => Ok(l),
| ^^^^^^ expected &Expr, found enum `Expr`
|
= note: expected type `&Expr`
= note: found type `Expr`
我想我理解第一个错误:我试图做的事情超出了我所允许的(不可变的)借阅范围self
,但是我不确定第二个错误。我不知道如何正确执行此操作。
对于第一个问题,您需要使用ref
@Adrian所说的关键字:
impl Expr {
fn eval(&self, env: &mut Env) -> Result<u32, String> {
use Expr::*;
match *self {
Lit(l) => Ok(l),
Var(ref id) => env.lookup(id).ok_or_else(|| format!("undefined var {:?}", id)),
Ass(ref id, v) => {
env.assign(id.clone(), v);
Ok(v)
}
Add(f, s) => Ok(f + s),
Sub(f, s) => Ok(f - s),
Mul(f, s) => Ok(f * s),
}
}
}
使用ref
可以防止模式匹配获得的所有权id
。正如您提到的,您不允许从中id
提取值,Expr
因为您只有一个不变的引用。v
,f
并且s
不会出现此问题,因为它们是u32
实现的Copy
。与其复制价值,不如复制价值,保留原始价值。
我不知道什么Env
或Id
类型的,或者的定义lookup
和assign
,因此,或许一些clone()
调用是没有必要的。
对于第二个问题,这是因为self
类型为&Expr
,因此您需要&
在模式中包括:
impl Expr {
fn eval(&self, env: &mut Env) -> Result<u32, String> {
use Expr::*;
match self {
&Lit(l) => Ok(l),
&Var(ref id) => env.lookup(id).ok_or_else(|| format!("undefined var {:?}", id)),
&Ass(ref id, v) => {
env.assign(id.clone(), v);
Ok(v)
}
&Add(f, s) => Ok(f + s),
&Sub(f, s) => Ok(f - s),
&Mul(f, s) => Ok(f * s),
}
}
}
两种匹配形式都是等效的,但是*self
更加惯用且需要更少的输入:)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句