gpt4 book ai didi

delegates - 为可以委托(delegate)的解析器借用检查器问题

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

我有几个解析器。有一个顶级的可以委托(delegate)给另一个。

Parser我们从 Reader 中获取他们的输入(可变)。我只想要一个 Parser为了能够一次解析,只有一个解析器应该有 Reader .

我通过为顶级解析器创建一个枚举来做到这一点,该解析器可以是读取器,也可以是委托(delegate)解析器(具有读取器)。这样它只能在未委托(delegate)时读取,这就是我想要的。

从顶层解析器,我需要可变地借用这个枚举来确定要做什么并获得读取器或委托(delegate)解析器。问题是,如果我想开始或停止委派,我需要移动 Reader大约。但此时它仍然是可变借用的。

我创建了一个最小示例,并且包含了关于 replace 的评论中的建议。和非词汇生命周期:

#![feature(nll)]
use std::mem::replace;

struct Reader {
i: u8,
}
impl Reader {
fn next(&mut self) -> u8 {
/* some logic here */
self.i += 1;
self.i
}
}

trait Parser {
fn parse(&mut self) -> u8;
}

enum ReaderOrDelegate {
Read(Reader),
Delegate(AnotherParser), /* Trait object in reality, but keeping it simple here. */
}

struct OneParser {
reader_or_delegate: ReaderOrDelegate,
}
impl Parser for OneParser {
fn parse(&mut self) -> u8 {
match self.reader_or_delegate {
ReaderOrDelegate::Delegate(ref mut delegate) => {
match delegate.parse() {
0 => {
replace(&mut self.reader_or_delegate, ReaderOrDelegate::Read(delegate.consume()));
self.parse()
},
x => 2 * x
}
},
ReaderOrDelegate::Read(ref mut reader) => {
match reader.next() {
0 => {
replace(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
self.parse()
},
x => 3 * x
}
},
}
}
}

struct AnotherParser {
reader: Reader,
}
impl AnotherParser {
fn consume(self) -> Reader {
self.reader
}
}
impl Parser for AnotherParser {
fn parse(&mut self) -> u8 {
self.reader.next() * 2
}
}

有了评论建议,还有一个错误:

error[E0308]: mismatched types
--> src/main.rs:42:106
|
42 | replace(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
| ^^^^^^ expected struct `Reader`, found &mut Reader
|
= note: expected type `Reader`
found type `&mut Reader`

我相信我可以通过 reader 解决这个问题来自 ReaderOrDelegate并将其作为 Rc<RefCell<Parser>>> 放入每个解析器中.但我认为将它放在枚举中更合乎逻辑:一次应该只有一个解析器能够使用阅读器。这可能吗?

我知道在这种情况下错误是有道理的,但我觉得在高层次上,应该可以做我想做的事。 Reader 只需要一个所有者.

编辑:对我来说,replace 的问题似乎很重要可以通过“嵌套”应用于这种情况(reader 已经被 match 借用,然后想要交换一个字段)。因此,虽然可能相关,但我认为另一个问题不足以解决这个问题。反正不适合我。

编辑 2:在代码示例和错误中包含注释建议。

最佳答案

考虑这一行:

replace(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));

你需要一个reader值(value),而不是引用,构建anotherParser :

error[E0308]: mismatched types
--> src/main.rs:42:106
|
42 | replace(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
| ^^^^^^ expected struct `Reader`, found &mut Reader
|
= note: expected type `Reader`
found type `&mut Reader`

但不可能获得这样的值(value)。如果我们尝试:

ReaderOrDelegate::Read(reader) => {
match reader.next() {
0 => {
replace(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
self.parse()
},
x => 3 * x
}
},

我们现在找到了您设计的真正问题:

error[E0507]: cannot move out of borrowed content
--> src/main.rs:39:36
|
39 | ReaderOrDelegate::Read(reader) => {
| ^^^^^^ cannot move out of borrowed content

parse方法借鉴​​self这意味着在这一点上我们不能从中移出拥有的值(value)借来的self .

另请注意错误 E0507也适用于该行:

replace(&mut self.reader_or_delegate, ReaderOrDelegate::Read(delegate.consume()));

因为consume尝试从借来的 delegate 中移出一个值.

在你的代码中,编译器没有显示这个问题,但如果你注释掉显然是你的示例中唯一存在的问题的行,它就会出现。

我能够安排的唯一解决方案,不会引起借用检查器错误,也不会转换太多你的设计是基于使用引用计数器 Reader ,在顶级解析器和委托(delegate)解析器之间共享。

Rc<Reader>您只有一个阅读器通过智能指针与您的解析器共享。

ReadOrDelegate enum 仅指示事件的解析器,没有更多的读者可以四处移动。

#![feature(nll)]
use std::rc::Rc;

struct Reader {
i: u8,
}

impl Reader {
fn next(&mut self) -> u8 {
/* some logic here */
self.i += 1;
self.i
}
}

trait Parser {
fn parse(&mut self) -> u8;
}

enum ReaderOrDelegate {
Read,
Delegate,
}

struct OneParser {
reader_or_delegate: ReaderOrDelegate,
reader: Rc<Reader>,
delegate: AnotherParser
}

impl Parser for OneParser {
fn parse(&mut self) -> u8 {
match self.reader_or_delegate {
ReaderOrDelegate::Delegate => {
match self.delegate.parse() {
0 => {
self.reader_or_delegate = ReaderOrDelegate::Read;
self.parse()
},
x => 2 * x
}
},
ReaderOrDelegate::Read => {
match Rc::get_mut(&mut self.reader).unwrap().next() {
0 => {
self.reader_or_delegate = ReaderOrDelegate::Delegate;
self.parse()
},
x => 3 * x
}
},
}
}
}

struct AnotherParser {
reader: Rc<Reader>
}

impl Parser for AnotherParser {
fn parse(&mut self) -> u8 {
Rc::get_mut(&mut self.reader).unwrap().next() * 2
}
}

关于delegates - 为可以委托(delegate)的解析器借用检查器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50535022/

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