type erasure for functions in rust

Viewed 316

Consider this C++ code:

#include <iostream>
#include <functional>

using namespace std;

std::function<int(int, int)> foo(int c) {
  auto add = [] (int a, int b) { return a + b; };
  auto sub = [] (int a, int b) { return a - b; };
  if (c > 42) {
    return add;
  } else {
    return sub;
  }
}

int main() {
  cout << foo(100)(10, 20) << '\n';
}

Both lambdas (add and sub) are type erased via std::function and that function is then called in main. I am wondering how can I replicate this pattern in rust?

1 Answers

A rather exact translation of your example would be the following snippet.

fn foo(c: i32) -> Box<dyn Fn(i32, i32) -> i32> {
    let add = |a, b| a + b;
    let sub = |a, b| a - b;
    Box::new(if c > 42 { add } else { sub })
}

fn main() {
    println!("{}", foo(100)(10, 20));
}

A type of closure is unnameable, so we coerce it to a trait object and store it on the heap, which is as far as I understand, is about the same thing std::function does.

Related