Enums 将函数应用于可能更改变量类型的枚举变量的惯用方法是什么?

Enums 将函数应用于可能更改变量类型的枚举变量的惯用方法是什么?,enums,rust,Enums,Rust,我有一个带有两个变量的枚举,还有一个函数可能会更改枚举的活动变量。我还想在两个枚举变量之间分割代码,但这带来了一个挑战,即变量类型的函数不能对自身进行可变引用,因为它不能更改它不属于的枚举变量。如果函数拥有所有权,我必须使用一个虚拟变量,这对于我的实际应用程序来说很好,但一般来说不是 struct Integer (i32); struct Natural (u32); enum Number { I(Integer), N(Natural), } impl Integer {

我有一个带有两个变量的枚举,还有一个函数可能会更改枚举的活动变量。我还想在两个枚举变量之间分割代码,但这带来了一个挑战,即变量类型的函数不能对自身进行可变引用,因为它不能更改它不属于的枚举变量。如果函数拥有所有权,我必须使用一个虚拟变量,这对于我的实际应用程序来说很好,但一般来说不是

struct Integer (i32);
struct Natural (u32);
enum Number {
    I(Integer),
    N(Natural),
}

impl Integer {
    // Decrement
    fn dec(&mut self) {
        self.0 -= 1;
    }
}

impl Natural {
    // Zero is a natural number that when decremented is not a natural number
    // therefore dec cannot take a &mut self
    fn dec(self) -> Number {
        if self.0 == 0 {
            Number::I(Integer(-1))
        } else {
            Number::N(Natural(self.0 - 1))
        }
    }
}

impl Number {
    // Is there a better way to do this?
    fn dec(&mut self) {
        let result = match self {
            Number::I(int) => {
                int.dec();
                return
            }
            Number::N(nat) => {
                // For this example making a dummy is possible
                // but what if it's not?
                let dummy = Natural(0);
                let extracted = std::mem::replace(nat, dummy);
                extracted.dec()
            }
        };
        *self = result;
    }
}

// Something like this would be nice
fn transform<T, F>(val: &mut T, f: F) where F : FnOnce(T) -> T {
    todo!("Magic!");
}

struct整数(i32);
struct-Natural(u32);
枚举数{
I(整数),
N(天然),
}
impl整数{
//减量
fn dec(和多个自身){
自相关系数0-=1;
}
}
纯天然{
//零是一个自然数,递减时不是自然数
//因此,dec不能接受多个自身(&M)
fn dec(自身)->编号{
如果self.0==0{
编号::I(整数(-1))
}否则{
编号::N(自然(自0-1))
}
}
}
impl数{
//有更好的方法吗?
fn dec(和多个自身){
让结果=匹配自我{
编号::I(int)=>{
int.dec();
返回
}
编号::N(nat)=>{
//在本例中,制作假人是可能的
//但如果不是呢?
设虚拟=自然(0);
让extracted=std::mem::replace(nat,dummy);
摘自
}
};
*自我=结果;
}
}
//像这样的东西会很好
fn变换(val:&mut T T,f:f),其中f:FnOnce(T)->T{
托多!(“魔术!”);
}

所有这些感觉都有点乏味,所以我怀疑我错过了一些更简单的方法。

如果应用函数可以更改枚举变量,那么在枚举变量的级别上实现它是没有意义的。我只想在枚举级别实现它,如下所示:


impl数{
fn dec(和多个自身){
*self=匹配self{
Number::I(I)=>Number::I(整数(I.0-1)),
Number::N(N)如果N.0==0=>Number::I(整数(-1)),
数字::N(N)=>数字::N(自然(N.0-1))
}
}
}
如果您确实希望在变体级别使用此功能,那么至少在
Natural::dec
的情况下,它不会总是成功的。因此,函数需要返回某个值,以指示不可能将其减量并且仍然保持为自然数的情况

impl整数{
fn dec(和多个自身){
自相关系数0-=1;
}
}
结构NotNatural();
纯天然{
fn dec(&mut self)->结果{
如果self.0==0{
Err(NotNatural())
}否则{
自相关系数0-=1;
好(())
}
}
}
impl数{
fn dec(和多个自身){
匹配自我{
编号::I(ref mut I)=>I.dec(),
编号::N(ref mut N)=>匹配N.dec(){
好的()=>(),
错误(41;)=>{
*self=Number::I(整数(-1));
()
}
}
}
}
}

对于我来说,natural不应该为nat=0实现dec,这毫无意义,应该报告一个错误