rhai/doc/src/rust/operators.md
2020-07-08 09:48:25 +08:00

2.4 KiB

Operator Overloading

{{#include ../links.md}}

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 is not built in, but calls a function named "+" instead!

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 ||. 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.

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.