Wie im IRC schon geklärt ist ein match-Statement das einfachste und offensichtlichste. Die primitiven mathematischen Operationen sind in Rust wie in vielen anderen Sprachen (C, Java, Go, etc) nicht sogenannte Funktionen höherer Ordnung Funktionen die man herumreichen kann (anders als z.B. in Haskell). Es gibt jedoch abstrakte Interfaces in std::ops die zum Überladen der Operatoren gedacht sind, die hier verwendet werden können. Beispiel:
use std::ops::Add;
fn main() {
let op = Add::<i32>::add;
println!("{}", op(1, 2)); // 3
}
Eigentlich wollte ich jetzt schreiben, dass das fehlende Subtyping bei Traits in Rust dich daran hindert, einfach Code zu schreiben, der sowohl für Add als auch für z.B. Mul beides funktioniert. Allerdings bilden freistehende Funktionen (fn Typen) in Rust jedoch eine Ausnahme wo es Subtyping gibt weil sie alle als Funktionspointer verwendet werden können. Dementsprechend funktioniert folgender Code zu meiner kompletten Überraschung:
use std::ops::{Add, Div, Mul, Sub};
fn main() {
let sym = "-";
let op = match sym {
"+" => Add::<i32>::add,
"-" => Sub::<i32>::sub,
"*" => Mul::<i32>::mul,
"/" => Div::<i32>::div,
_ => panic!("ungültiger Operator"),
};
println!("{}", op(1, 2)); // -1
}
Alles anzeigen
Playground: https://play.rust-lang.org/?gist=662de9bc…&version=stable
Man lernt halt nie aus. op ist dabei vom Typ fn(i32, i32) -> i32, also eine beliebige freistehende Funktion die zwei i32 nimmt und ein i32 zurückgibt.