Array access describes the particular syntax traditionally used to access a value in an array at a certain offset. This is usually only allowed with arguments of type Int
. Using abstracts, however, makes it possible to define custom array access methods. The Haxe Standard Library uses this in its Map
type, where the following two methods can be found:
@:arrayAccess public inline function get(key:K) { return this.get(key); } @:arrayAccess public inline function arrayWrite(k:K, v:V):V { this.set(k, v); return v; }
There are two kinds of array access methods:
@:arrayAccess
method accepts one argument, it is a getter.@:arrayAccess
method accepts two arguments, it is a setter.The methods get
and arrayWrite
seen above then allow for the following usage:
class Main { public static function main() { var map = new Map(); map["foo"] = 1; trace(map["foo"]); } }
At this point, it should not be surprising to see that calls to the array access fields are inserted into the output:
map.set("foo",1); console.log(map.get("foo")); // 1
Due to a bug in Haxe versions before 3.2, the order of checked @:arrayAccess
fields was undefined. This was fixed for Haxe 3.2 so that the fields are now consistently checked from top to bottom:
abstract AString(String) { public function new(s) this = s; @:arrayAccess function getInt1(k:Int) { return this.charAt(k); } @:arrayAccess function getInt2(k:Int) { return this.charAt(k).toUpperCase(); } } class Main { static function main() { var a = new AString("foo"); trace(a[0]); // f } }
The array access a[0]
is resolved to the getInt1
field, leading to the lower case f
being returned. The result might be different in Haxe versions before 3.2.
Fields which are defined earlier take priority even if they require an implicit cast.