gpt4 book ai didi

parsing - 使用 match 查看 stdin

转载 作者:行者123 更新时间:2023-11-29 08:18:43 24 4
gpt4 key购买 nike

我正在尝试将旧编译器教科书中的翻译器/解析器示例从 C 移植到 Rust。

我有以下代码:

use std::io::Read;

fn lexan() {
let mut input = std::io::stdin().bytes().peekable();
loop {
match input.peek() {
Some(&ch) => {
match ch {
_ => println!("{:?}", input.next()),
}
}
None => break,
}
}
}

此时我并没有主动尝试解析输入,只是想了解 match 是如何工作的。目的是将解析分支添加到内部匹配中。不幸的是,这无法编译,因为我似乎无法理解匹配的语义:

error[E0507]: cannot move out of borrowed content
--> src/main.rs:7:18
|
7 | Some(&ch) => {
| ^--
| ||
| |hint: to prevent move, use `ref ch` or `ref mut ch`
| cannot move out of borrowed content

据我了解,这个错误是因为我不拥有match 的返回值。问题是,我不相信我正在使用任一匹配项的返回值。我认为 input.next() 可能是问题所在,但不管有没有这部分(或者实际上,整个 println! 调用)都会出现同样的错误。

我在这里错过了什么?自从我研究 Rust 以来已经有一段时间了(而且从来没有认真研究过),并且大多数针对这种性质的东西的搜索结果似乎已经过时了。

最佳答案

match的返回值无关,甚至 match本身::

use std::io::Read;

fn lexan() {
let mut input = std::io::stdin().bytes().peekable();
if let Some(&ch) = input.peek() {}
}

问题是您正在尝试绑定(bind) Peekable::peek 的结果在取消引用时(这就是 & 中的 &ch 所做的)。在这种情况下,返回类型是 Option<&Result<u8, std::io::Error>>因为Bytes迭代器从底层流返回错误。由于此类型未实现 Copy ,尝试取消引用该类型需要您转移该值的所有权。您不能这样做,因为您不拥有原始值——因此会出现错误消息。

导致无法复制的那一 block 是Result的错误类型.因此,您可以匹配更深一层:

match input.peek() {
Some(&Ok(ch)) => {
match ch {
_ => println!("{:?}", input.next()),
}
}
Some(&Err(_)) => panic!(),
None => break,
}

请注意,这段代码几乎无法编译。 peek的结果next时会失效被调用,所以对这段代码的如此多的小改动将触发借用检查器使代码失败。事实上,我有点惊讶上面的方法在第一次尝试时就起作用了。

如果你根本不关心错误,你可以这样做

while let Some(&Ok(ch)) = input.peek() {
match ch {
_ => println!("{:?}", input.next()),
}
}

不幸的是,您不能拆分中间部分,因为这会导致借用 input。在通话期间持续 next :

while let Some(x) = input.peek() {
match *x {
Ok(ch) => {
match ch {
_ => println!("{:?}", input.next()),
}
}
Err(_) => {}
}

// Could still use `x` here, compiler doesn't currently see that we don't
}

关于parsing - 使用 match 查看 stdin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45177131/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com