95 lines
3.7 KiB
Markdown
95 lines
3.7 KiB
Markdown
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()`](type-of.md) an exclusive range returns `"range"`.
|
|
|
|
### Inclusive range
|
|
|
|
> _start_ `..=` _end_
|
|
|
|
An _inclusive_ range includes the last (i.e. "end") value.
|
|
|
|
[`type_of()`](type-of.md) an inclusive range returns `"range="`.
|
|
|
|
|
|
Usage Scenarios
|
|
---------------
|
|
|
|
Ranges are commonly used in the following scenarios.
|
|
|
|
| Scenario | Example |
|
|
| -------------------------------------------- | --------------------------------------- |
|
|
| [`for`](for.md) statements | `for n in 0..100 { ... }` |
|
|
| [`in`](operators.md) expressions | `if n in 0..100 { ... }` |
|
|
| [`switch`](switch.md) expressions | `switch n { 0..100 => ... }` |
|
|
| [Bit-fields](bit-fields.md) access | `let x = n[2..6];` |
|
|
| Bits iteration | `for bit in n.bits(2..=9) { ... }` |
|
|
| [Array](arrays.md) range-based APIs | `array.extract(2..8)` |
|
|
| [BLOB](blobs.md) range-based APIs | `blob.parse_le_int(4..8)` |
|
|
| [String](strings-chars.md) range-based APIs | `string.sub_string(4..=12)` |
|
|
| [Characters](strings-chars.md) iteration | `for ch in string.bits(4..=12) { ... }` |
|
|
|
|
|
|
Built-in Functions
|
|
------------------
|
|
|
|
The following methods operate on ranges.
|
|
|
|
| Function | Parameter(s) | Description |
|
|
| ---------------------------------- | :-------------: | --------------------------------------------- |
|
|
| `start` method and property | | beginning of the range |
|
|
| `end` method and property | | end of the range |
|
|
| `contains`, `in` operator | number to check | does this range contain the specified number? |
|
|
| `is_empty` method and property | | returns `true` if the range contains no items |
|
|
| `is_inclusive` method and property | | is the range inclusive? |
|
|
| `is_exclusive` method and property | | is the range exclusive? |
|
|
|
|
|
|
TL;DR
|
|
-----
|
|
|
|
```admonish question "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.
|
|
|
|
~~~rust
|
|
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'
|
|
~~~
|
|
```
|