Un oggetto può essere spostato attraverso un'espressione di corrispondenza? [chiuso]

2

Sto usando Rust 1.15.1 e, recentemente, mi sono imbattuto in un problema per il quale non sono riuscito a trovare una soluzione immediata.

Quando si guardano gli esempi usando la corrispondenza dei pattern, solitamente distruggono l'oggetto nell'espressione della corrispondenza e continuano a lavorare con i membri all'interno di quell'oggetto. Tuttavia, mi piacerebbe NON distruggerlo, ma combaciare solo con esso e inviare l'oggetto completo (usando la semantica del movimento) a una delle tante altre funzioni a seconda delle sue proprietà.

Il seguente codice funziona e fa esattamente ciò di cui ho bisogno. Tuttavia, ho bisogno di introdurre un tipo enum "artificiale" e una seconda espressione di corrispondenza. Mi chiedo se esiste una soluzione più semplice e più semplice?

#[derive(Debug)]
enum Number {
    Constant { value: i32 },
}

fn process_even(n: Number) {
    println!("even: {:?}", n);
}

fn process_odd(n: Number) {
    println!("odd: {:?}", n);
}

fn process(n: Number) {
    enum Action {
        ProcessEven,
        ProcessOdd,
    }

    let action = match n {
        Number::Constant { value: c, .. } if 0 == c % 2 => Action::ProcessEven,
        _ => Action::ProcessOdd,
    };

    match action {
        Action::ProcessEven => process_even(n),
        Action::ProcessOdd => process_odd(n),
    }
}

fn main() {
    process(Number::Constant { value: 4711 });
    process(Number::Constant { value: 2000 });
}
    
posta Jonny Dee 12.03.2017 - 04:35
fonte

1 risposta

1

Hai provato solo utilizzando n ?

fn process(n: Number) {
    match n {
        Number::Constant { value: c, .. } if c % 2 == 0 => process_even(n),
        _ => process_odd(n)
    }
}

Funziona perché value è i32 , che è Copy , il che significa che il compilatore può copiarlo senza bisogno di spostarlo o prenderlo a prestito. Se hai a che fare con tipi più complicati, potresti non essere in grado di evitare il secondo stadio.

Detto questo, anche nel caso che , se hai solo due opzioni, puoi restituire true o false . O potresti restituire process_even / process_odd direttamente come puntatori di funzione dalla prima corrispondenza e chiamare quello:

fn process(n: Number) {
    let action = match n {
        Number::Constant { value: c, .. } if c % 2 == 0 => process_even as fn(_),
        _ => process_odd
    };

    action(n)
}
    
risposta data 12.03.2017 - 04:41
fonte

Leggi altre domande sui tag