如何解决Haxe中的“重复构造函数”错误?

时间:2019-09-07 17:45:07

标签: constructor duplicates haxe

在Haxe中,我创建了一个名为 MyClass 的类,例如:

class MyClass {

    var score: String;

    public function new (score: Int) {
        this.score = Std.string(score);
    }

    public function new (score: String) {
        this.score = score;
    }
 }

我需要多个构造函数,但Haxe不允许我这样做。它将在构建阶段引发此错误:

*.hx:*: lines * : Duplicate constructor
The terminal process terminated with exit code: 1

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:6)

这称为方法重载,Haxe不支持{em> externs(但might be in the future)。有多种方法可以解决此问题。

对于构造函数,通常的解决方法是为第二个构造函数使用静态的“工厂方法”:

class MyClass {
    var score:String;

    public function new(score:String) {
        this.score = score;
    }

    public static function fromInt(score:Int):MyClass {
        return new MyClass(Std.string(score));
    }
}

您还可以有一个接受两种参数的构造函数:

class MyClass {
    var score:String;

    public function new(score:haxe.extern.EitherType<String, Int>) {
        // technically there's no need for an if-else in this particular case, since there's
        // no harm in calling `Std.string()` on something that's already a string
        if (Std.is(score, String)) {
            this.score = score;
        } else {
            this.score = Std.string(score);   
        }
    }
}

但是,我不推荐这种方法,haxe.extern.EitherType本质上是Dynamic,对类型安全性和性能不利。同样,EitherType从技术上仅旨在用于外部元素。

更安全的类型,但也更冗长的选项是haxe.ds.Either<String, Int>。在这里,您必须显式调用枚举构造函数:new MyClass(Left("100")) / new MyClass(Right(100)),然后使用pattern matching提取值。


支持StringInt中的abstract typeimplicit conversions也可能是一个选项:

class Test {
    static function main() {
        var s1:Score = "100";
        var s2:Score = 100;
    }
}

abstract Score(String) from String {
    @:from static function fromInt(i:Int):Score {
        return Std.string(i);
    }
}

最后,还有an experimental library添加了对宏的重载支持,但我不确定它是否支持构造函数。

答案 1 :(得分:1)

我建议使用类型参数

class MyClass<T> {
    var score:String;

    public function new(score:T) {
        this.score = Std.string(score);
    }
}

您还可以在构造函数中使用类型参数

class MyClass {
    var score:String;

    public function new<T>(score:T) {
        this.score = Std.string(score);
    }
}

但是,在构造函数中使用的T在运行时(CS和Java)失败,但尚未修复(Haxe 4)。否则,您可以这样做

class MyClass {
    var score:String;

    @:generic public function new<@:const T>(score:T) {
        this.score = Std.is(T, String) ? untyped score : Std.string(score);
    }
}

可以很好地产生这样的代码(CS)

        __hx_this.score = ( (( T is string )) ? (score) : (global::Std.@string(score)) );

仅当T不是字符串时才调用Std.string()。

答案 2 :(得分:0)

嘿,

使用一个简单的示例,您可以执行类似function new( ?s : String, ?n : Int ){}的操作,Haxe将按类型使用正确的参数。但是您可以执行new(),也许您不想这么做。