Ranges

Syntax

Numeric ranges can be constructed by the .. (exclusive) or ..= (inclusive) operators.

Exclusive range

start .. end

An exclusive range does not include the last (i.e. “end”) value.

type_of() an exclusive range returns "range".

Inclusive range

start ..= end

An inclusive range includes the last (i.e. “end”) value.

type_of() an inclusive range returns "range=".

Usage Scenarios

Ranges are commonly used in the following scenarios.

ScenarioExample
for statementsfor n in 0..100 { ... }
in expressionsif n in 0..100 { ... }
switch expressionsswitch n { 0..100 => ... }
Bit-fields accesslet x = n[2..6];
Bits iterationfor bit in n.bits(2..=9) { ... }
Array range-based API’sarray.extract(2..8)
BLOB range-based API’sblob.parse_le_int(4..8)
String range-based API’sstring.sub_string(4..=12)
Characters iterationfor ch in string.bits(4..=12) { ... }

Built-in Functions

The following methods operate on ranges.

FunctionParameter(s)Description
start method and propertybeginning of the range
end method and propertyend of the range
contains, in operatornumber to checkdoes this range contain the specified number?
is_inclusive method and propertyis the range inclusive?
is_exclusive method and propertyis the range exclusive?

TL;DR

What happened to the open-ended ranges?

Rust has open-ended ranges, such as start.., ..end and ..=end. They are not available in Rhai.

They are not needed because Rhai can overload functions.

Typically, an API accepting ranges as parameters would have equivalent versions that accept a starting position and a length (the standard start + len pair), as well as a versions that accept only the starting position (the length assuming to the end).

In fact, usually all versions redirect to a call to one single version.

Therefore, there should always be a function that can do what open-ended ranges are intended for.

The left-open form (i.e. ..end and ..=end) is trivially replaced by using zero as the starting position with a length that corresponds to the end position (for ..end).

The right-open form (i.e. start..) is trivially replaced by the version taking a single starting position.

let x = [1, 2, 3, 4, 5];

x.extract(0..3);    // normal range argument
                    // copies 'x' from positions 0-2

x.extract(2);       // copies 'x' from position 2 onwards
                    // equivalent to '2..'

x.extract(0, 2);    // copies 'x' from beginning for 2 items
                    // equivalent to '..2'