Using closures to avoid creating unnecessary variables in certain control flow

If an object owned this enum

enum Enum {
    A(u8)
    B
}

and the object wanted to do a computation and change the value in the case of the Enum::A variant, but didn't want to do this computation or create any memory in the Enum::B case, could the object avoid having to match on the enum by using a generic closure param like this

impl Object {
    fn bar(&mut self) {
        self.enum.mutate_if_a_variant(|| 1);
}
impl Enum {
    mutate_if_a_variant<F: FnOnce() -> u8>(&mut self, f: F) {
        if let Enum::A(x) = self {
            std::mem::replace(self, Enum::A(f() + x));
        }
     }
}

as opposed to these alternatives

impl Object
     fn bar(&mut self) {
         match self.enum {
             Enum::A(x) => ...

or

impl Enum {
    fn mutate_if_a_variant(&mut self, x: u8) ...

impl Object {
    fn bar(&mut self) {
        let x = 1; 
        self.enum.mutate_if_a_variant(x);
}

Is the closure option more "performant" in the general case? Obviously less performant in the Enum::A case because of the closure. The match statement is the best alternative, but the point here is that I don't want to do that in the body of functions outside impl Enum. The compiler still needs to know how much stack memory to allocate either way, but can I avoid unnecessary runtime computations with a closure param? let x = 1 admittedly doesn't demonstrate a serious computation, but it's just an example. Also, could a boxed closure avoid unnecessary memory allocation in the non Enum::A cases?

Sure. If you notice some sort of performance hit you could try marking the method inline.

A boxed closure won't avoid any allocations a non-boxed closure would avoid.

2 Likes

The standard library uses this pattern extensively, look at the methods of Option and Result for example. Your method is equivalent to Option::map, btw.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.