问题描述
我的问题是 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 的限制以及如何将外部库定义为 pip install ipykernel
而不是包装在抽象中。在 std/lua/Table.hx 中,extern
被定义为实现 ArrayAccess<B>
。这告诉 Haxe 该类型支持使用整数对其进行索引,并且元素类型为 Table<A,B>
。它无法表明允许的索引器类型是 B
。 ArrayAccess<T>
的文档说明:
这个接口应该只用于外部人员。 Haxe 不支持对类的自定义数组访问。但是,可以为抽象类型实现数组访问。
https://haxe.org/manual/types-abstract-array-access.html
您可以将 A
定义为简单的 lua.Table
,而不是将其定义为抽象。这将使您可以适当地指定数组设置器/获取器。执行此操作的示例如下。:
extern
需要使用 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>
中使用索引运算符。 Haxe 认为我们正在做的是为索引表达式提供一个整数值。摘要本身提供了 this[untyped k]
/K
类型的索引器。
我不知道为什么这不是 Haxe 标准库采用的方法。您可能会在他们的 GitHub 存储库中找到或提交错误以开始对此进行讨论。我不认为使 V
难以使用是故意的。