Correct speed claim and others in docs.
This commit is contained in:
@@ -178,22 +178,21 @@ Use `switch` Through Arrays
|
||||
---------------------------
|
||||
|
||||
Another way to work with Rust enums in a `switch` expression is through exposing the internal data
|
||||
of each enum variant as a variable-length [array], usually with the name of the variant as
|
||||
the first item for convenience:
|
||||
(or at least those that act as effective _discriminants_) of each enum variant as a variable-length
|
||||
[array], usually with the name of the variant as the first item for convenience:
|
||||
|
||||
```rust
|
||||
use rhai::Array;
|
||||
|
||||
engine.register_get("enum_data", |x: &mut Enum| {
|
||||
match x {
|
||||
Enum::Foo => vec![
|
||||
"Foo".into()
|
||||
] as Array,
|
||||
Enum::Foo => vec![ "Foo".into() ] as Array,
|
||||
|
||||
Enum::Bar(value) => vec![
|
||||
"Bar".into(), (*value).into()
|
||||
] as Array,
|
||||
// Say, skip the data field because it is not
|
||||
// used as a discriminant
|
||||
Enum::Bar(value) => vec![ "Bar".into() ] as Array,
|
||||
|
||||
// Say, all fields act as discriminants
|
||||
Enum::Baz(val1, val2) => vec![
|
||||
"Baz".into(), val1.clone().into(), (*val2).into()
|
||||
] as Array
|
||||
@@ -208,8 +207,7 @@ Then it is a simple matter to match an enum via the `switch` expression:
|
||||
// 'enum_data' creates a variable-length array with 'MyEnum' data
|
||||
let x = switch value.enum_data {
|
||||
["Foo"] => 1,
|
||||
["Bar", 42] => 2,
|
||||
["Bar", 123] => 3,
|
||||
["Bar"] => value.field_1,
|
||||
["Baz", "hello", false] => 4,
|
||||
["Baz", "hello", true] => 5,
|
||||
_ => 9
|
||||
@@ -220,10 +218,20 @@ x == 5;
|
||||
// Which is essentially the same as:
|
||||
let x = switch [value.type, value.field_0, value.field_1] {
|
||||
["Foo", (), ()] => 1,
|
||||
["Bar", 42, ()] => 2,
|
||||
["Bar", 123, ()] => 3,
|
||||
["Bar", 42, ()] => 42,
|
||||
["Bar", 123, ()] => 123,
|
||||
:
|
||||
["Baz", "hello", false] => 4,
|
||||
["Baz", "hello", true] => 5,
|
||||
_ => 9
|
||||
}
|
||||
```
|
||||
|
||||
Usually, a helper method returns an array of values that can uniquely determine
|
||||
the switch case based on actual usage requirements - which means that it probably
|
||||
skips fields that contain data instead of discriminants.
|
||||
|
||||
Then `switch` is used to very quickly match through a large number of array shapes
|
||||
and jump to the appropriate case implementation.
|
||||
|
||||
Data fields can then be extracted from the enum independently.
|
||||
|
@@ -26,10 +26,10 @@ Use Closures to Define Methods
|
||||
-----------------------------
|
||||
|
||||
[Anonymous functions] or [closures] defined as values for [object map] properties take on
|
||||
a syntactic shape that resembles very closely that of class methods in an OOP language.
|
||||
a syntactic shape which resembles very closely that of class methods in an OOP language.
|
||||
|
||||
Closures also _[capture][automatic currying]_ variables from the defining environment, which is a very
|
||||
common OOP pattern. Capturing is accomplished via a feature called _[automatic currying]_ and
|
||||
common language feature. Capturing is accomplished via a feature called _[automatic currying]_ and
|
||||
can be turned off via the [`no_closure`] feature.
|
||||
|
||||
|
||||
@@ -59,3 +59,51 @@ factor = 2;
|
||||
obj.update(42);
|
||||
obj.action(); // prints 84
|
||||
```
|
||||
|
||||
|
||||
Simulating Inheritance With Mixin
|
||||
--------------------------------
|
||||
|
||||
The `fill_with` method of [object maps] can be conveniently used to _polyfill_ default
|
||||
method implementations from a _base class_, as per OOP lingo.
|
||||
|
||||
Do not use the `mixin` method because it _overwrites_ existing fields.
|
||||
|
||||
```rust
|
||||
// Define base class
|
||||
let BaseClass = #{
|
||||
factor: 1,
|
||||
data: 42,
|
||||
|
||||
get_data: || this.data * 2,
|
||||
update: |x| this.data += x * this.factor
|
||||
};
|
||||
|
||||
let obj = #{
|
||||
// Override base class field
|
||||
factor: 100,
|
||||
|
||||
// Override base class method
|
||||
// Notice that the base class can also be accessed, if in scope
|
||||
get_data: || this.call(BaseClass.get_data) * 999,
|
||||
}
|
||||
|
||||
// Polyfill missing fields/methods
|
||||
obj.fill_with(BaseClass);
|
||||
|
||||
// By this point, 'obj' has the following:
|
||||
//
|
||||
// #{
|
||||
// factor: 100
|
||||
// data: 42,
|
||||
// get_data: || this.call(BaseClass.get_data) * 999,
|
||||
// update: |x| this.data += x * this.factor
|
||||
// }
|
||||
|
||||
// obj.get_data() => (this.data (42) * 2) * 999
|
||||
obj.get_data() == 83916;
|
||||
|
||||
obj.update(1);
|
||||
|
||||
obj.data == 142
|
||||
```
|
||||
|
Reference in New Issue
Block a user