简体   繁体   English

重载 AsRef<T> 通过使用它来解开 Rust 中的枚举?

[英]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:我强烈建议您不要这样做,特别是考虑到AsRefAsMut的文档以粗体显示:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM