我正在尝试学习Rust,所以如果我走的话请忍受:-)
我有一个程序,将枚举插入到HashMap,并使用Strings作为键。我正在尝试匹配的内容HashMap。问题是我无法弄清楚如何在eval_output函数中获得正确的借用,引用和类型。该eval_output函数应如何正确处理对a的引用HashMap?我可以阅读任何良好的文档以了解有关此特定主题的更多信息吗?
use std::prelude::*;
use std::collections::HashMap;
enum Op {
Not(String),
Value(u16),
}
fn eval_output(output: &str, outputs: &HashMap<String, Op>) -> u16 {
match outputs.get(output) {
Some(&op) => {
match op {
Op::Not(input) => return eval_output(input.as_str(), outputs),
Op::Value(value) => return value,
}
}
None => panic!("Did not find input for wire {}", output),
}
}
fn main() {
let mut outputs = HashMap::new();
outputs.insert(String::from("x"), Op::Value(17));
outputs.insert(String::from("a"), Op::Not(String::from("x")));
println!("Calculated output is {}", eval_output("a", &outputs));
}
Run Code Online (Sandbox Code Playgroud)
查看什么是编译器错误消息:
error: cannot move out of borrowed content [E0507]
Some(&op) => {
^~~
note: attempting to move value to here
Some(&op) => {
^~
help: to prevent the move, use `ref op` or `ref mut op` to capture value by reference
Run Code Online (Sandbox Code Playgroud)
尽管从技术上讲是正确的,但使用起来Some(ref op)有点愚蠢,因为类型op会是双引用(&&Op)。相反,我们只需删除&和即可Some(op)。
这是一个困扰人们的常见错误,因为要正确使用它,您必须熟悉模式匹配和引用,再加上Rust严格的借位检查器。当你有的时候Some(&op),那说
匹配的
Option是变体Some。在Some必须包含的值的参考。所指事物应从其所在位置移出并放入op。
模式匹配时,这两个关键字ref和mut可以起作用。它们不是模式匹配的,而是它们控制如何将值绑定到变量名。它们是&和的类似物mut。
这导致我们进入下一个错误:
error: mismatched types:
expected `&Op`,
found `Op`
Op::Not(input) => return eval_output(input.as_str(), outputs),
^~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
match *some_reference在可能的情况下最好这样做,但是在这种情况下您不能这样做。因此,我们需要更新模式以匹配对Op— 的引用&Op。看看接下来会发生什么错误...
error: cannot move out of borrowed content [E0507]
&Op::Not(input) => return eval_output(input.as_str(), outputs),
^~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
是我们以前的朋友。这次,我们将遵循编译器的建议,并将其更改为ref input。还有更多变化,我们有:
use std::collections::HashMap;
enum Op {
Not(String),
Value(u16),
}
fn eval_output(output: &str, outputs: &HashMap<String, Op>) -> u16 {
match outputs.get(output) {
Some(op) => {
match op {
&Op::Not(ref input) => eval_output(input, outputs),
&Op::Value(value) => value,
}
}
None => panic!("Did not find input for wire {}", output),
}
}
fn main() {
let mut outputs = HashMap::new();
outputs.insert("x".into(), Op::Value(17));
outputs.insert("a".into(), Op::Not("x".into()));
println!("Calculated output is {}", eval_output("a", &outputs));
}
Run Code Online (Sandbox Code Playgroud)
不需要use std::prelude::*;-编译器自动插入。
as_str在稳定的Rust中不存在。对String(&String)的引用可以使用deref强制来充当字符串切片(&str)。
我用into代替,String::from因为它有点短。没有更好的理由。
| 归档时间: |
|
| 查看次数: |
301 次 |
| 最近记录: |