in Operator

The in operator is used to check for containment – i.e. whether a particular collection data type contains a particular item.

Standard data types with built-in support for the in operator are:


#![allow(unused)]
fn main() {
42 in [1, "abc", 42, ()] == true;   // check array for item

"foo" in #{                         // check object map for property name
    foo: 42,
    bar: true,
    baz: "hello"
} == true;

'w' in "hello, world!" == true;     // check string for character

"wor" in "hello, world" == true;    // check string for sub-string
}

Array Items Comparison

The default implementation of the in operator for arrays uses the == operator (if defined) to compare items.

Beware that, for a custom type, == defaults to false when comparing it with a value of of the same type.

See the section on Logic Operators for more details.


#![allow(unused)]
fn main() {
let ts = new_ts();                  // assume 'new_ts' returns a custom type

let a = [1, 2, 3, ts, 42, 999];     // array contains custom type

42 in a == true;                    // 42 cannot be compared with 'ts'
                                    // so it defaults to 'false'
                                    // because == operator is not defined
}

Custom Implementation of contains

The in operator maps directly to a call to a function contains with the two operands switched.

For example:


#![allow(unused)]
fn main() {
item in container
}

maps to the following function call:


#![allow(unused)]
fn main() {
contains(container, item)
}

Support for the in operator can be easily extended to other types by registering a custom binary function named contains with the correct parameter types.

For example:


#![allow(unused)]
fn main() {
engine.register_type::<TestStruct>()
      .register_fn("new_ts", || TestStruct::new())
      .register_fn("contains", |container: &mut TestStruct, item: i64| -> bool {
          // Remember the parameters are switched from the 'in' expression
          container.contains(item)
      });
}

Now the in operator can be used for TestStruct:


#![allow(unused)]
fn main() {
let ts = new_ts();

if 42 in ts {                       // this calls the 'contains' function
    print("I got 42!");
}

let err = "hello" in ts;            // <- runtime error: 'contains' not found
}