Operator Overloading

In Rhai, a lot of functionalities are actually implemented as functions, including basic operations such as arithmetic calculations.

For example, in the expression “a + b“, the + operator calls a function named “+“!


#![allow(unused)]
fn main() {
let x = a + b;

let x = +(a, b);        // <- the above is equivalent to this function call
}

Similarly, comparison operators including ==, != etc. are all implemented as functions, with the stark exception of && and ||.

&& and || Cannot Be Overloaded

Because they short-circuit, && and || are handled specially and not via a function; as a result, overriding them has no effect at all.

Overload Operator via Rust Function

Operator functions cannot be defined as a script function (because operators syntax are not valid function names).

However, operator functions can be registered to the Engine via the methods Engine::register_fn, Engine::register_result_fn etc.

When a custom operator function is registered with the same name as an operator, it overrides the built-in version.


#![allow(unused)]
fn main() {
use rhai::{Engine, EvalAltResult, RegisterFn};

let mut engine = Engine::new();

fn strange_add(a: i64, b: i64) -> i64 { (a + b) * 42 }

engine.register_fn("+", strange_add);               // overload '+' operator for two integers!

let result: i64 = engine.eval("1 + 0");             // the overloading version is used

result == 42;

let result: f64 = engine.eval("1.0 + 0.0");         // '+' operator for two floats not overloaded

result == 1.0;

fn mixed_add(a: i64, b: f64) -> f64 { (a as f64) + b }

engine.register_fn("+", mixed_add);                 // register '+' operator for an integer and a float

let result: i64 = engine.eval("1 + 1.0");           // <- normally an error...

result == 2.0;                                      //    ... but not now
}

Considerations

Normally, use operator overloading for custom types only.

Be very careful when overriding built-in operators because script authors expect standard operators to behave in a consistent and predictable manner, and will be annoyed if a calculation for ‘+‘ turns into a subtraction, for example.

Operator overloading also impacts script optimization when using OptimizationLevel::Full. See the [script-optimization] for more details.