在我的代码中,我定义了一个
trait Node
,这个特征是我使用的每个特征的“父”。我如何定义一个函数,其中 return type
是实现此特征的 some struct ?目前特征是这样定义的:
pub trait Node {
fn token(&self) -> Token;
}
pub trait Statement: Node {
fn statement_node(&self);
}
pub trait Expression: Node {
fn expression_type(&self) -> ExpressionType;
}
我有两种
Node structs
:Statement
和Expression
:
pub struct LetStatement {
pub token: Token,
}
impl Node for LetStatement {
fn node_type(&self) -> NodeType {}
}
impl Statement for LetStatement {
fn statement_node(&self) {}
}
pub struct Expression {
pub token: Token,
}
impl Node for LetStatement {
fn node_type(&self) -> NodeType {}
}
impl Expression for LetStatement {
fn statement_node(&self) {}
}
在该函数的简化版本中,我会有类似的内容:
fn parse_statement(&mut self) -> Box<dyn Node> {
match statement {
"let" => self.parse_let_statement(),
"return" => self.parse_return_statement(),
_ => self.parse_expression_statement(),
}
}
这种方法的主要问题是,通过这种返回,从辅助函数返回的所有结构都会“转换”为
Node
,而没有在特征 expression
和 statement
中定义的特定函数
如果您希望能够返回多种值中的一种,但让它们保留其独特的行为,您有两种选择:
Node
)。第二个选项在 Rust 中更简单、更惯用。
pub enum Node {
Statement(Statement),
Expression(Expression),
}
给定
Node
,您可以在其上 match
来检查或提取内部值。
match some_node {
Node::Statement(stmt) => { stmt.statement_node(); }
Node::Expression(expr) => { expr.expression_type(); }
}
请注意,您可能希望完全删除特征并一直使用枚举。例如,
Statement
可以是一个枚举,其变体包括 Let(LetStatement)
。