当我尝试从 class 外部访问字段时,为什么我的 getter 没有被调用?

Why are my getters not called when I'm trying to access a field from outside the class?

我开始了解 Haxe,我主要用它来生成 Python 代码和 C# DLL。

但是我 运行 多次遇到同一个问题:每当我尝试编写 getter 时,当我从方法内部访问相关 属性 时它们工作正常,但是当我尝试从 class 之外访问它们甚至都没有被调用。我开始怀疑我错过了一些基本的东西。

例如,如果我写以下内容 class:

@:expose
@:keep
class TestClass
{
    public var testField(get, null):String;

    private function get_testField():String
    {
        trace("executing getter");
        return "testString";
    }

    public function new() {}

    public function testMethod()
    {
        trace(testField);
    }
}

然后在 Python:

testInstance = MyModule.TestClass();
testInstance.testMethod();

...按预期输出:

executing getter
testString

但是

print(testInstance.testField)

...输出 None.

在所有情况下,我都希望 testInstance.testField 到 return "testString",我做错了什么?这也在 C# 中发生。

这是因为 properties in Haxe are a compile-time feature 并且不生成本机属性。并不是所有的目标都有属性,那些有属性的目标可能不会 100% 匹配 Haxe 的语义。

相反,属性 访问在编译时被访问器方法(get_field()set_field())的调用所取代。因此,

trace(testField);

编译为Python时变成如下:

print(str(self.get_testField()))

因此,为了获得一致的结果,您还必须在 Python 端调用 get_testField()

对于 C# 和 Flash 目标,存在用于生成本机属性的元数据(请参阅 haxe --help-metas):

@:property - Marks a property field to be compiled as a native C# property (cs only)

@:getter - (Class field name) Generates a native getter function on the given field (flash only)

@:setter - (Class field name) Generates a native setter function on the given field (flash only)

请注意,C# 目标的 @:property 仅适用于没有 physical field 的属性。在您的示例中,(get, null) 必须替换为 (get, never) 才能正常工作。

目前还有一个 open feature request 用于通过 @:property 支持 JS 目标上的本机属性。这对于 Python 也可能有意义,考虑到它也具有原生属性。也许考虑打开一个问题。 :)