reorganize module
This commit is contained in:
183
_archive/rhai_engine/rhaibook/language/variables.md
Normal file
183
_archive/rhai_engine/rhaibook/language/variables.md
Normal file
@@ -0,0 +1,183 @@
|
||||
Variables
|
||||
=========
|
||||
|
||||
{{#include ../links.md}}
|
||||
|
||||
|
||||
Valid Names
|
||||
-----------
|
||||
|
||||
```admonish tip.side.wide "Tip: Unicode Standard Annex #31 identifiers"
|
||||
|
||||
The [`unicode-xid-ident`] feature expands the allowed characters for variable names to the set defined by
|
||||
[Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/).
|
||||
```
|
||||
|
||||
Variables in Rhai follow normal C naming rules – must contain only ASCII letters, digits and underscores `_`.
|
||||
|
||||
| Character set | Description |
|
||||
| :-----------: | ------------------------ |
|
||||
| `A` ... `Z` | Upper-case ASCII letters |
|
||||
| `a` ... `z` | Lower-case ASCII letters |
|
||||
| `0` ... `9` | Digit characters |
|
||||
| `_` | Underscore character |
|
||||
|
||||
However, unlike Rust, a variable name must also contain at least one ASCII letter, and an ASCII
|
||||
letter must come _before_ any digits. In other words, the first character that is not an underscore `_`
|
||||
must be an ASCII letter and not a digit.
|
||||
|
||||
```admonish question.side.wide "Why this restriction?"
|
||||
|
||||
To reduce confusion (and subtle bugs) because, for instance, `_1` can easily be misread (or mistyped)
|
||||
as `-1`.
|
||||
|
||||
Rhai is dynamic without type checking, so there is no compiler to catch these typos.
|
||||
```
|
||||
|
||||
Therefore, some names acceptable to Rust, like `_`, `_42foo`, `_1` etc., are not valid in Rhai.
|
||||
|
||||
For example: `c3po` and `_r2d2_` are valid variable names, but `3abc` and `____49steps` are not.
|
||||
|
||||
Variable names are case _sensitive_.
|
||||
|
||||
Variable names also cannot be the same as a [keyword] (active or reserved).
|
||||
|
||||
```admonish warning.small "Avoid names longer than 11 letters on 32-Bit"
|
||||
|
||||
Rhai uses [`SmartString`] which avoids allocations unless a string is over its internal limit
|
||||
(23 ASCII characters on 64-bit, but only 11 ASCII characters on 32-bit).
|
||||
|
||||
On 64-bit systems, _most_ variable names are shorter than 23 letters, so this is unlikely to become
|
||||
an issue.
|
||||
|
||||
However, on 32-bit systems, take care to limit, where possible, variable names to within 11 letters.
|
||||
This is particularly true for local variables inside a hot loop, where they are created and
|
||||
destroyed in rapid succession.
|
||||
|
||||
~~~js
|
||||
// The following is SLOW on 32-bit
|
||||
for my_super_loop_variable in array {
|
||||
print(`Super! ${my_super_loop_variable}`);
|
||||
}
|
||||
|
||||
// Suggested revision:
|
||||
for loop_var in array {
|
||||
print(`Super! ${loop_var}`);
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
|
||||
Declare a Variable
|
||||
------------------
|
||||
|
||||
Variables are declared using the `let` keyword.
|
||||
|
||||
```admonish tip.small "Tip: No initial value"
|
||||
|
||||
Variables do not have to be given an initial value.
|
||||
If none is provided, it defaults to [`()`].
|
||||
```
|
||||
|
||||
```admonish warning.small "Variables are local"
|
||||
|
||||
A variable defined within a [statements block](statements.md) is _local_ to that block.
|
||||
```
|
||||
|
||||
~~~admonish tip.small "Tip: `is_def_var`"
|
||||
|
||||
Use `is_def_var` to detect if a variable is defined.
|
||||
~~~
|
||||
|
||||
```rust
|
||||
let x; // ok - value is '()'
|
||||
let x = 3; // ok
|
||||
let _x = 42; // ok
|
||||
let x_ = 42; // also ok
|
||||
let _x_ = 42; // still ok
|
||||
|
||||
let _ = 123; // <- syntax error: illegal variable name
|
||||
let _9 = 9; // <- syntax error: illegal variable name
|
||||
|
||||
let x = 42; // variable is 'x', lower case
|
||||
let X = 123; // variable is 'X', upper case
|
||||
|
||||
print(x); // prints 42
|
||||
print(X); // prints 123
|
||||
|
||||
{
|
||||
let x = 999; // local variable 'x' shadows the 'x' in parent block
|
||||
|
||||
print(x); // prints 999
|
||||
}
|
||||
|
||||
print(x); // prints 42 - the parent block's 'x' is not changed
|
||||
|
||||
let x = 0; // new variable 'x' shadows the old 'x'
|
||||
|
||||
print(x); // prints 0
|
||||
|
||||
is_def_var("x") == true;
|
||||
|
||||
is_def_var("_x") == true;
|
||||
|
||||
is_def_var("y") == false;
|
||||
```
|
||||
|
||||
|
||||
Use Before Definition
|
||||
---------------------
|
||||
|
||||
By default, variables do not need to be defined before they are used.
|
||||
|
||||
If a variable accessed by a script is not defined previously within the same script, it is assumed
|
||||
to be provided via an external custom [`Scope`] passed to the [`Engine`] via the
|
||||
`Engine::XXX_with_scope` API.
|
||||
|
||||
```rust
|
||||
let engine = Engine::new();
|
||||
|
||||
engine.run("print(answer)")?; // <- error: variable 'answer' not found
|
||||
|
||||
// Create custom scope
|
||||
let mut scope = Scope::new();
|
||||
|
||||
// Add variable to custom scope
|
||||
scope.push("answer", 42_i64);
|
||||
|
||||
// Run with custom scope
|
||||
engine.run_with_scope(&mut scope,
|
||||
"print(answer)" // <- prints 42
|
||||
)?;
|
||||
```
|
||||
|
||||
~~~admonish bug.small "No `Scope`"
|
||||
|
||||
If no [`Scope`] is used to evaluate the script (e.g. when using `Engine::run` instead of
|
||||
`Engine::run_with_scope`), an undefined variable causes a runtime error when accessed.
|
||||
~~~
|
||||
|
||||
|
||||
Strict Variables Mode
|
||||
---------------------
|
||||
|
||||
With [`Engine::set_strict_variables`][options], it is possible to turn on
|
||||
[_Strict Variables_][strict variables] mode.
|
||||
|
||||
When [strict variables] mode is active, accessing a variable not previously defined within
|
||||
the same script directly causes a parse error when compiling the script.
|
||||
|
||||
```rust
|
||||
let x = 42;
|
||||
|
||||
print(x); // prints 42
|
||||
|
||||
print(foo); // <- parse error under strict variables mode:
|
||||
// variable 'foo' is undefined
|
||||
```
|
||||
|
||||
```admonish tip.small
|
||||
|
||||
Turn on [strict variables] mode if no [`Scope`] is to be provided for script evaluation runs.
|
||||
This way, variable access errors are caught during compile time instead of runtime.
|
||||
```
|
Reference in New Issue
Block a user