Haxe 2 から 3 へ

Haxe のバージョンを 2.10 から 3.0.0 に更新した。
Haxe 2 の時のコードが結構動かなくなったので、変更点をメモ。

interface 継承の変更

implements -> extends

  • haxe 2
interface Hoge {}
interface Piyo implements Hoge {}
  • haxe 3
interface Hoge {}
interface Piyo extends Hoge {}

複数 interface を実装する場合の指定の変更

implements A, implements B -> implements A implements B

  • haxe 2
interface A {}
interface B {}
class C implements A, implements B {}
  • haxe 3
interface A {}
interface B {}
class C implements A implements B {}

構造的部分型の配列を作る際の初期化子の型が厳密化

構造体と型 で、「えー」っていってたのができなくなった。

  • haxe 2
using Lambda;
typedef X = { id: Int, name: String, msg: String, hoge: Int }
class Hoge {
	public static function hoge(x: List<X>) {}
	public static function main() {
		hoge([{ name: "hoge" }, { msg: "hoge" }].list());
	}
}
  • haxe 3
using Lambda;
typedef X = { id: Int, name: String, msg: String, hoge: Int }
class Hoge {
	public static function hoge(x: List<X>) {}
	public static function main() {
		hoge([
			{ id: null, name: "hoge", msg: null, hoge: null },
			{ id: null, name: null, msg: "hoge", hoge: null },
		].list());
	}
}

ヘテロな配列を作る際に、Array の指定が必須

  • haxe 2
class Hoge {
	public static function main() {
		var as = [{ name: "hoge" }, { msg: "hoge" }];
		trace(as);
	}
}
  • haxe 3
class Hoge {
	public static function main() {
		var as: Array<Dynamic> = [{ name: "hoge" }, { msg: "hoge" }];
		trace(as);
	}
}

Std.format 廃止

Std.format("~") -> '~'

  • haxe 2
class Hoge {
	public static function main() {
		var x = 10;
		var str = Std.format("${x}");
		trace(str);
	}
}
  • haxe 3
class Hoge {
	public static function main() {
		var x = 10;
		var str = '${x}';
		trace(str);
	}
}

window などが、js.Lib -> js.Browser に移動

  • haxe 2
class Hoge {
	public static function main() {
		var url = js.Lib.window.location.href;
		trace(url);
	}
}
  • haxe 3
class Hoge {
	public static function main() {
		var url = js.Browser.window.location.href;
		trace(url);
	}
}

Array の first メソッド等廃止

  • haxe 2
class Hoge {
	public static function main() {
		var xs = [1, 2, 3];
		var x = xs.first();
		trace(x);
	}
}
  • haxe 3
class Hoge {
	public static function main() {
		var xs = [1, 2, 3];
		var x = xs[0];
		trace(x);
	}
}

Void 型の扱いが変更

  • haxe 2
using Lambda;
class Hoge {
	public static function main() {
		var f: Void -> Int = function(x) { return 1; };
		var xs: List<Void> = [null, null].list();
		var ys = xs.map(f);
		trace(ys);
	}
}
  • haxe 3
class Hoge {
	public static function main() {
		var f: Void -> Int = function() { return 1; };
		var xs: List<Void> = [null, null].list();
		//var ys = xs.map(f); // error: Void -> Int should be (Void) -> Unknown<0>
		//trace(ys);
	}
}

関数型内の Dynamic で Void が受け取れなくなった

  • haxe 2
using Lambda;
class Hoge {
	public static function hoge(x: List<Dynamic>) {}
	public static function piyo(f: Int -> Dynamic) {}
	public static function main() {
		var xs: List<Void> = [null, null].list();
		hoge(xs);
		var f: Int -> Void = function(x) {};
		piyo(f);
	}
}
  • haxe 3
using Lambda;
class Hoge {
	public static function hoge(x: List<Dynamic>) {}
	public static function piyo<T>(f: Int -> T) {}
	public static function main() {
		var xs: List<Void> = [null, null].list();
		hoge(xs);
		var f: Int -> Void = function(x) {};
		piyo(f);
	}
}

Hash 廃止

Hash -> Map

  • haxe 2
class Hoge {
	public static function main() {
		var m: Hash<Int> = new Hash();
		m.set("hoge", 1);
	}
}
  • haxe 3
class Hoge {
	public static function main() {
		var m: Map<String, Int> = new Map();
		m.set("hoge", 1);
	}
}

生成されるJSがお行儀よくなった

  • "use strict" がつくようになった
  • 無名関数にくくられ、グローバルを汚さないようになった

Haxe側にあるパッケージと同じ名前空間をJS側からexportしたい場合にうまく動かない

ローカル変数で実現されているパッケージが、グローバルの名前を隠蔽してしまう。

hoge/aa/AA.hx

package hoge.aa;
extern class AA {
	public static function create(): AA;
}

hoge/Hoge.hx

  • haxe 2
package hoge;
import hoge.aa.AA;
class Hoge {
	public static function main() {
		var a = AA.create();
		trace(a);
	}
}
  • haxe 3
package hoge;
import hoge.aa.AA;
class Hoge {
	public static function main() {
		//var a = AA.create(); // runtime error: Cannot read property 'AA' of undefined
		var a: AA = untyped __js__("window.hoge.aa.AA.create()");
		trace(a);
	}
}