摘要的正确用途

时间:2014-12-24 23:07:49

标签: haxe

就在昨天,我决定在过去几年使用Actionscript 3之后开始学习Haxe编程语言。今天我一直在探索抽象类型,我逐渐意识到它们与Java中的抽象类有很大的不同。我开始掌握他们所做的一些事情,但我不确定用什么摘要。是什么构成了在Haxe中正确使用摘要,什么时候我应该在课堂上赞成它们?

例如,下面是使用抽象类型的复数类型的不完整定义。我应该更喜欢这个还是只是一个普通的班级?

abstract Complex({real:Float, imag:Float}) {
    public function new(real:Float, imag:Float) {
        this = { real: real, imag: imag };
    }

    public function real():Float {  return this.real; }
    public function imag():Float {  return this.imag; }

    @:op(A + B)
    public static function add(lhs:Complex, rhs:Complex):Complex {
        return new Complex(lhs.real() + rhs.real(), lhs.imag() + rhs.imag());
    }

    public function toString():String {
        return real() + " + " + imag() + "i";
    }
}

1 个答案:

答案 0 :(得分:22)

实际上,摘要与Java中的抽象类完全不同。 Haxe中的抽象类型功能强大且有趣。它们的主要特征是它们是仅在编译时存在的类型。在运行时,它们完全被包装类型取代。方法转换为静态函数。在您描述的情况下,您的所有实例都将被包含两个字段realimag的匿名对象替换。这是一个很好的用例吗?可能是的,因为复杂类型不是要扩展的,你可能想要定义一些运算符重载(就像你为添加做的那样)。

为了让它更轻盈,你可以使用Array<Float>作为包裹类型,其中第一个元素是真实部分,第二个元素是虚构元素。

那么抽象类型的优点是什么?

  • 他们将语义添加到类型(特别是原始类型)。例如,您可以定义abstract RGB(Int) {}以始终使用方法和属性输出非常有效的颜色编码。或者您可以使用abstract Path(String) {}来方便地处理路径连接,相对路径等。
  • 您可以定义运算符重载。在上面的例子中,您可以执行white + black之类的操作,并从中获取有意义的内容。
  • 与运算符重载类似,摘要可以定义来自其他类型的隐式转换。对于上面的RGB,您可以轻松定义方法fromString()以将十六进制字符串解析为表示颜色的Int。使用隐式转换,您可以执行:var color : RGB = "#669900";thx.color定义了许多用于颜色处理的摘要。
  • 他们非常适合将非常强大的Enums包裹在Haxe中。使用抽象,您可以向枚举添加方法和属性(本身不支持任何这些)。
  • 它们是包装优化代码的理想选择。可以内联抽象方法,并且包装类型可确保在执行代码时不添加任何额外的间接层。

什么不太好?或者更好的是,我们应该知道什么是摘要?

  • 因为它们只是一个编译时工件,所以不能使用运行时检查(例如:no Std.is(value, MyAbstract))。
  • 摘要不是类,所以没有继承。