通过使用 AsRef<T> 在 Rust 中解包枚举来重载它?
Overloading AsRef<T> by using it to unwrap enums in Rust?
我正在使用 AsRef<T>
和 AsMut<T>
来公开枚举中的包装值。谁能告诉我这是否是反模式?我遇到了 ,它让我相信 Deref
是个坏主意,但我不确定下面的方法。
pub enum Node {
Stmt(Statement),
Expr(Expression),
}
impl AsMut<Expression> for Node {
fn as_mut(&mut self) -> &mut Expression {
match self {
Node::Stmt(_) => panic!("fatal: expected Expression"),
Node::Expr(e) => e,
}
}
}
impl AsMut<Expression> for Box<Node> {
fn as_mut(&mut self) -> &mut Expression {
(**self).as_mut()
}
}
impl AsMut<Expression> for Expression {
fn as_mut(&mut self) -> &mut Expression {
self
}
}
fn check_binop<T: AsMut<Expression>>(
&mut self,
sym: Symbol,
lhs: &mut T,
rhs: &mut T,
ty: &mut Option<Type>,
) -> Result<Type, String> {
let lhs = lhs.as_mut();
let rhs = rhs.as_mut();
...
}
我正在考虑制作我自己的特征(AsExpr<T>
和 AsExprMut<T>
),它们只是 AsRef<T>
和 AsMut<T>
的重新实现。功能上没有什么不同,但我认为它会更清楚。
我强烈建议你不要这样做,特别是考虑到 AsRef
和 AsMut
的文档用粗体表示:
Note: This trait must not fail.
而且我肯定会认为恐慌是失败的。这不是 anti-pattern ,因为它通过实施这些特征违反了你 opt-into 的合同。您应该考虑返回一个 Option<&mut Expression>
而不是通过 AsRef
/AsMut
,或者像您提到的那样创建您自己的特征。
我正在使用 AsRef<T>
和 AsMut<T>
来公开枚举中的包装值。谁能告诉我这是否是反模式?我遇到了 Deref
是个坏主意,但我不确定下面的方法。
pub enum Node {
Stmt(Statement),
Expr(Expression),
}
impl AsMut<Expression> for Node {
fn as_mut(&mut self) -> &mut Expression {
match self {
Node::Stmt(_) => panic!("fatal: expected Expression"),
Node::Expr(e) => e,
}
}
}
impl AsMut<Expression> for Box<Node> {
fn as_mut(&mut self) -> &mut Expression {
(**self).as_mut()
}
}
impl AsMut<Expression> for Expression {
fn as_mut(&mut self) -> &mut Expression {
self
}
}
fn check_binop<T: AsMut<Expression>>(
&mut self,
sym: Symbol,
lhs: &mut T,
rhs: &mut T,
ty: &mut Option<Type>,
) -> Result<Type, String> {
let lhs = lhs.as_mut();
let rhs = rhs.as_mut();
...
}
我正在考虑制作我自己的特征(AsExpr<T>
和 AsExprMut<T>
),它们只是 AsRef<T>
和 AsMut<T>
的重新实现。功能上没有什么不同,但我认为它会更清楚。
我强烈建议你不要这样做,特别是考虑到 AsRef
和 AsMut
的文档用粗体表示:
Note: This trait must not fail.
而且我肯定会认为恐慌是失败的。这不是 anti-pattern ,因为它通过实施这些特征违反了你 opt-into 的合同。您应该考虑返回一个 Option<&mut Expression>
而不是通过 AsRef
/AsMut
,或者像您提到的那样创建您自己的特征。