Haxe lua.Table<String, Int>: String 应该是 Int
Haxe lua.Table<String, Int>: String should be Int
我的问题是 haxe 不想将以下代码片段编译到 lua 目标。它抱怨:
Main.hx:7: characters 11-17 : String should be Int
import lua.Table;
class Main {
static public function my_test(): Table<String, Int>
{
var t: Table<String, Int> = Table.create();
t["test"] = 1; # Heres the problem
return t;
}
static public function main(): Void
{
var x = my_test();
trace(x);
}
}
如果我将有问题的行更改为:
t[1] = 1;
奇怪的是它没有抱怨,这对我来说似乎不合逻辑,因为在我的理解中它是错误的类型。
如果我将 $type(t)
放在上面代码片段的某处,它会正确地将其识别为 lua.Table<String, Int>
。
我查看了 std/lua/Table.hx
的源代码,并根据那里的一些代码,在我的代码片段中使用了 untyped
关键字:t[untyped "test"] = 1;
只有这样它才能生成所需的 lua 代码执行成功:
Main.my_test = function()
local t = ({});
t.test = 1;
do return t end;
end
虽然我期待这样的事情:
Main.my_test = function()
local t = {};
t["test"] = 1;
do return t end;
end
那么,为什么我必须使用这个关键字?
$ haxe --version
4.2.1+bf9ff69
# I compile with
$ haxe -D lua-vanilla --main Main --lua Main.lua
这似乎是 Haxe 的限制,以及外部库如何定义为 extern
而不是包装在抽象中。在 std/lua/Table.hx, Table<A, B>
is defined as implementing ArrayAccess<B>
. This tells Haxe that the type supports indexing into it with integers and that the element type is B
. There is no way for it to indicate that the allowed indexer type is A
. ArrayAccess<T>
的文档中指出:
This interface should be used for externs only. Haxe does not support custom array access on classes. However, array access can be implemented for abstract types.
不是以这种方式将 lua.Table
定义为简单的 extern
,您可以将其周围的包装器定义为抽象。这将使您可以适当地指定一个数组 setter/getter 。下面是一个这样做的例子。:
extern class LuaGTable<A, B> implements ArrayAccess<B> {
}
abstract MyLuaTable<K, V>(LuaGTable<K, V>) {
inline public function new() {
this = untyped __lua__("({})");
}
@:arrayAccess
public inline function set(k: K, v) {
this[untyped k] = v;
}
@:arrayAccess
public inline function get(k: K) {
return this[untyped k];
}
}
需要使用 implements ArrayAccess<B>
才能完全允许在表达式 this[untyped k]
中使用索引运算符。 Haxe 认为我们正在做的是为索引表达式提供一个整数值。摘要本身提供 K
/V
类型的索引器。
我不知道为什么这不是 Haxe 标准库采用的方法。您可能会在他们的 GitHub 存储库中找到或提交错误以开始对此进行讨论。我不认为让 Table<A, B>
难以使用是故意的。
我的问题是 haxe 不想将以下代码片段编译到 lua 目标。它抱怨:
Main.hx:7: characters 11-17 : String should be Int
import lua.Table;
class Main {
static public function my_test(): Table<String, Int>
{
var t: Table<String, Int> = Table.create();
t["test"] = 1; # Heres the problem
return t;
}
static public function main(): Void
{
var x = my_test();
trace(x);
}
}
如果我将有问题的行更改为:
t[1] = 1;
奇怪的是它没有抱怨,这对我来说似乎不合逻辑,因为在我的理解中它是错误的类型。
如果我将 $type(t)
放在上面代码片段的某处,它会正确地将其识别为 lua.Table<String, Int>
。
我查看了 std/lua/Table.hx
的源代码,并根据那里的一些代码,在我的代码片段中使用了 untyped
关键字:t[untyped "test"] = 1;
只有这样它才能生成所需的 lua 代码执行成功:
Main.my_test = function()
local t = ({});
t.test = 1;
do return t end;
end
虽然我期待这样的事情:
Main.my_test = function()
local t = {};
t["test"] = 1;
do return t end;
end
那么,为什么我必须使用这个关键字?
$ haxe --version
4.2.1+bf9ff69
# I compile with
$ haxe -D lua-vanilla --main Main --lua Main.lua
这似乎是 Haxe 的限制,以及外部库如何定义为 extern
而不是包装在抽象中。在 std/lua/Table.hx, Table<A, B>
is defined as implementing ArrayAccess<B>
. This tells Haxe that the type supports indexing into it with integers and that the element type is B
. There is no way for it to indicate that the allowed indexer type is A
. ArrayAccess<T>
的文档中指出:
This interface should be used for externs only. Haxe does not support custom array access on classes. However, array access can be implemented for abstract types.
不是以这种方式将 lua.Table
定义为简单的 extern
,您可以将其周围的包装器定义为抽象。这将使您可以适当地指定一个数组 setter/getter 。下面是一个这样做的例子。:
extern class LuaGTable<A, B> implements ArrayAccess<B> {
}
abstract MyLuaTable<K, V>(LuaGTable<K, V>) {
inline public function new() {
this = untyped __lua__("({})");
}
@:arrayAccess
public inline function set(k: K, v) {
this[untyped k] = v;
}
@:arrayAccess
public inline function get(k: K) {
return this[untyped k];
}
}
需要使用 implements ArrayAccess<B>
才能完全允许在表达式 this[untyped k]
中使用索引运算符。 Haxe 认为我们正在做的是为索引表达式提供一个整数值。摘要本身提供 K
/V
类型的索引器。
我不知道为什么这不是 Haxe 标准库采用的方法。您可能会在他们的 GitHub 存储库中找到或提交错误以开始对此进行讨论。我不认为让 Table<A, B>
难以使用是故意的。