【问题标题】:How can I solve 'Duplicate Constructor' error in Haxe?如何解决 Haxe 中的“重复构造函数”错误?
【发布时间】:2019-09-07 17:45:07
【问题描述】:

在 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

我该如何解决这个问题?

【问题讨论】:

    标签: constructor duplicates haxe


    【解决方案1】:

    这称为方法重载,除了externs(但might be in the future)之外,Haxe 不支持这种方法。您可以通过多种方式解决此问题。

    在构造函数的情况下,一个常见的解决方法是为第二个构造函数使用静态“工厂方法”:

    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&lt;String, Int&gt; 是一个更类型安全但也更冗长的选项。在这里,您必须显式调用枚举构造函数:new MyClass(Left("100")) / new MyClass(Right(100)),然后使用pattern matching 提取值。


    StringInt 支持implicit conversionsabstract type 也可能是一个选项:

    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 增加了对宏的重载支持,但我不确定它是否支持构造函数。

    【讨论】:

      【解决方案2】:

      我推荐使用类型参数

      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()。

      【讨论】:

        【解决方案3】:

        嘿嘿,

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

        【讨论】:

          猜你喜欢
          • 2021-06-14
          • 1970-01-01
          • 1970-01-01
          • 2021-08-14
          • 2020-05-30
          • 1970-01-01
          • 1970-01-01
          • 2014-12-17
          相关资源
          最近更新 更多