Important: this article is written about Haxe 3.1.3. It works well in Haxe 3.2 🙂
Few days ago I wrote about eight things I don’t like in Haxe, and one of thing was tricky unsafe cast syntax:
(cast findViewById(R.id.myTextView):TextView).setText("Cool");
compared to safe cast:
cast(findViewById(R.id.myTextView), TextView).setText("Cool");
However I was wrong. This unsafe cast work fine only on dynamic targets, but on cpp it cause compilation error:
class A { public function new() { } } class B extends A { public function foo():Void { trace("foo"); } } class Test { private static function bar(a:A):Void { (cast a:B).foo(); } public static function main() { bar(new B()); } }
work fine for neko, javascript or flash, but on cpp:
error: no member named 'foo' in 'A_obj'
🙁
UPD: As mentioned here, Std.instance() should be used as one-line unsafe cast. However this is not true:
haxe - Std.instance(a, B).foo(); js - ((a instanceof B) ? a : null).foo(); cpp - ::Std_obj::instance(a, hx::ClassOf<::B>())->__Field(HX_CSTRING("foo"), true)();
Pretty much cpp code, and additional check in js code 🙁 . Compare to unsafe cast:
haxe - var b:B = cast a; b.foo(); js - var b = a; b.foo(); cpp - ::B b = a; b->foo();
Nice 🙂
By the way, this is code generated by the safe cast:
haxe - cast(a, B).foo(); js - (js.Boot.__cast(a , B)).foo(); cpp - (hx::TCast<B>::cast(a))->foo();
For cpp it is even better than Std.instance().