[英]Overloading AsRef<T> by using it to unwrap enums in Rust?
I'm using AsRef<T>
and AsMut<T>
to expose an wrapped value in an enum.我正在使用
AsRef<T>
和AsMut<T>
在枚举中公开包装的值。 Can anyone tell me if this is an anti-pattern?谁能告诉我这是否是反模式? I came across Is it considered a bad practice to implement Deref for newtypes?
我遇到了为新类型实现 Deref 是否被认为是一种不好的做法? , and it convinced me that
Deref
would be a bad idea, but I'm not sure about the approach below. ,它让我相信
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();
...
}
I'm considering just making my own traits ( AsExpr<T>
and AsExprMut<T>
) that are just re-implementations of AsRef<T>
and AsMut<T>
.我正在考虑制作我自己的特征(
AsExpr<T>
和AsExprMut<T>
),它们只是AsRef<T>
和AsMut<T>
的重新实现。 Functionally no different, but I think it would be clearer.功能上没有什么不同,但我认为它会更清楚。
I strongly suggest you do not do this, especially considering the docs for AsRef
and AsMut
say in bold:我强烈建议您不要这样做,特别是考虑到
AsRef
和AsMut
的文档以粗体显示:
Note: This trait must not fail.
注意:这个特性不能失败。
and I would definitely consider panicking to be failure.我肯定会认为恐慌是失败的。 This isn't an anti-pattern so much as it is breaking the contract you opt-into by implementing those traits.
这不是一个反模式,因为它通过实现这些特征打破了您选择加入的合同。 You should consider returning an
Option<&mut Expression>
instead of going through AsRef
/ AsMut
, or making your own traits like you mentioned.您应该考虑返回
Option<&mut Expression>
而不是通过AsRef
/ AsMut
,或者像您提到的那样制作自己的特征。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.