Haxe lua.Table<String, Int>: String 应该是 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; # 这里有问题
        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

# 我使用以下命令进行编译
$ haxe -D lua-vanilla --main Main --lua Main.lua
点赞
用户429091
用户429091

这似乎是 Haxe 和外部库定义为 extern 而不是包装在抽象类中的限制。在 std/lua/Table.hx 中,Table<A,B> 被定义为实现 ArrayAccess<B>。这告诉 Haxe,该类型支持使用整数进行索引和元素类型是 B。它无法表示允许索引器类型为 AArrayAccess<T> 的文档说明:

此接口应仅用于外部类。Haxe 不支持自定义类的数组访问。但可以为抽象类型实现数组访问。

https://haxe.org/manual/types-abstract-array-access.html

你可以将 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> 难以使用是有意的。

2021-03-08 02:24:43