如何解决 Haxe 中的 'Duplicate Constructor' 错误?
How can I solve 'Duplicate Constructor' error in Haxe?
在 Haxe 中,我创建了一个名为 MyClass 的 class,例如:
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
我该如何解决这个问题?
这被称为 方法重载 ,除了 externs (but might be in the future 之外,Haxe 不支持它。有多种方法可以解决此问题。
对于构造函数,一个常见的解决方法是为第二个构造函数设置静态 "factory method":
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 提取值。
来自 String
和 Int
的 abstract type that supports implicit 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增加了对宏的重载支持,但我不确定它是否支持构造函数。
我推荐使用类型参数
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()。
他,
用一个简单的例子,你可以做类似的事情function new( ?s : String, ?n : Int ){}
,Haxe 将按类型使用正确的参数。但你可以做到 new()
,也许你不想。
在 Haxe 中,我创建了一个名为 MyClass 的 class,例如:
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
我该如何解决这个问题?
这被称为 方法重载 ,除了 externs (but might be in the future 之外,Haxe 不支持它。有多种方法可以解决此问题。
对于构造函数,一个常见的解决方法是为第二个构造函数设置静态 "factory method":
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 提取值。
来自 String
和 Int
的 abstract type that supports implicit 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增加了对宏的重载支持,但我不确定它是否支持构造函数。
我推荐使用类型参数
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()。
他,
用一个简单的例子,你可以做类似的事情function new( ?s : String, ?n : Int ){}
,Haxe 将按类型使用正确的参数。但你可以做到 new()
,也许你不想。