我希望能够遍历解析器数组,以尝试从主解析函数中查找委托解析器。解析器列表在编译时是已知的,因此我希望它是一个常量。
我尝试了一些这种方法,但是我无法使它起作用:
const ALL_PARSERS: [&Parser; 1] = [&CommentParser {}];
我该如何实现?
注意:
Parser
是一个特质。CommentParser
是实现Parser
的结构。Parser
的其他实现,但为简单起见未显示。我当前遇到的错误:
|
11 | const ALL_PARSERS: [&Parser; 1] = [&CommentParser {}];
| ^^^^^^^^^^^^ the trait `parsers::Parser` cannot be made into an object
|
= note: method `parse` has generic type parameters
我在解析方法中看不到任何泛型:
pub trait Parser {
fn opening_char(self: &Self) -> char;
fn parse(&mut self, env: impl ParserEnv) -> ParseResult;
}
const ALL_PARSERS: [Parser; 1] = [CommentParser {}];
错误变为:
11 | const ALL_PARSERS: [Parser; 1] = [CommentParser {}];
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn parsers::Parser + 'static)`
答案 0 :(得分:2)
特质引用需要标记为&dyn
,例如&dyn Parser
:
trait Parser { }
struct CommentParser { }
impl Parser for CommentParser { }
const ALL_PARSERS: [&dyn Parser; 1] = [&CommentParser {}];
fn main() {
for &parser in &ALL_PARSERS {
// do something with parser
}
}
此外,如相关问题的this answer所述,如果要进行特征引用,则特征中不能包含通用参数,因此您需要向该特征中添加通用类型特征本身,或在分析器类型中使用特征引用而不是impl
// original (with error)
trait Parser {
// impl ParserEnv is an implicit generic type
fn parse(&mut self, env: impl ParserEnv) -> ParseResult;
// same as:
// fn parser<E: ParserEnv>(&mut self, env: E) -> ParserResult;
}
// alternative 1, with trait generic type
trait Parser<E: ParserEnv> {
fn parse(&mut self, env: E) -> ParseResult;
}
// alternative 2, with trait reference
trait Parser {
fn parser(&mut self, env: &dyn ParserEnv) -> ParserResult;
// may need &dyn mut ParserEnv if you want to modify env as well
}
我认为第二种方法可能是最好的,因为这样您就可以将解析器存储在数组中,而无需为解析器分配特定的ParserEnv
类型。