我希望我的getv()函数从a返回值HashMap.无论我如何修改代码,我都会收到错误:
enum Type {
TyInt,
TyBool,
}
struct TypeEnv {
Env: HashMap<char, Type>,
}
impl TypeEnv {
fn set(&mut self, name: char, ty: Type) {
self.Env.insert(name, ty);
}
fn getv(self, name: char) -> Type {
match self.Env.get(&name) {
Some(Type) => Type, // <------- Always error here
None => Type::TyInt,
}
}
}
Run Code Online (Sandbox Code Playgroud)
HashMap::get返回一个Option<&Type>,而不是一个Option<Type>,这就是为什么只返回匹配的值无法编译.
get提供了一个引用,因为在Rust中你不能简单地返回哈希表中的实际值 - 你需要克隆它(制作副本,可能很昂贵),将其从容器中删除并将其传输给调用者,或者返回一个引用里面的值.HashMap::get选择最后一个选项,因为它是便宜的,同时为调用者提供最大的灵活性,可以选择检查值或克隆它.
对于由单个机器字组成的枚举,复制该值将是最佳方法.(对于更复杂的枚举,更好的方法是返回参考,如Simon的回答所示.)复制需要:
Type通过Copy使用#[derive(Copy, Clone)]类型定义中的指令用特征标记它来制作可复制的.
getv通过使用*matched_value或&在模式中使用取消引用匹配值来返回副本.
最后,您的getv方法使用对象,这意味着您只能调用一次.这几乎肯定不是预期的 - 它应该接受&self.通过这些更改,生成的代码如下所示:
use std::collections::HashMap;
#[derive(Copy, Clone)]
enum Type {
TyInt,
TyBool,
}
struct TypeEnv {
env: HashMap<char, Type>,
}
impl TypeEnv {
fn set(&mut self, name: char, ty: Type) {
self.env.insert(name, ty);
}
fn getv(&self, name: char) -> Type {
match self.env.get(&name) {
Some(&v) => v,
None => Type::TyInt,
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果类型需要包含非Copy数据,那么您只能Clone改为使用,然后返回v.clone().
| 归档时间: |
|
| 查看次数: |
840 次 |
| 最近记录: |