代码之家  ›  专栏  ›  技术社区  ›  Suragch Shmidt

命名构造函数是Dart中生成构造函数的子集吗?

  •  0
  • Suragch Shmidt  · 技术社区  · 4 年前

    Dart language tour

    class Point {
      double x, y;
    
      Point(double x, double y) {
        // There's a better way to do this, stay tuned.
        this.x = x;
        this.y = y;
      }
    }
    

    后面给出了一个例子 named constructor :

    class Point {
      double x, y;
    
      Point(this.x, this.y);
    
      // Named constructor
      Point.origin() {
        x = 0;
        y = 0;
      }
    }
    

    Point(this.x, this.y);
    

    但是如果有一个附加的标识符,那么它就是一个命名的构造函数:

    Point.origin() {
      x = 0;
      y = 0;
    }
    

    然而,在另一个 my answers

    术语“命名构造函数”似乎不在 language spec .

    0 回复  |  直到 4 年前
        1
  •  10
  •   lrn    4 年前

    构造函数或 工厂 factory 在前面,它是工厂构造器,否则它是生成构造器。

    生成构造函数总是创建 它所属的精确类的实例。 工厂构造函数(几乎)只是一个静态函数,返回类型是它所属的类的类型。它可以返回它的任何子类型,但它本身不创建任何新对象。

    命名 未命名 . 为了班级 Foo ,构造函数名为 是“unnamed”(或者,实际上是“empty named”)构造函数,并且 Foo.someName Dart没有 (同一范围内具有相同名称的多个声明,通常通过参数类型进行区分),因此如果没有命名构造函数,则每个类只能有一个构造函数。命名构造函数允许一个类拥有它想要的任意多个构造函数,并且每个构造函数都可以是该语言允许的构造函数的任何变体。

    构造函数可以是 转发 不转发 . 转发生成构造函数必须转发给同一类的生成构造函数。例子:

    class Point {
      final double x, y;
      const Point(this.x, this.y);  // Generative, unnamed, non-forwarding, const.
      const Point.diagonal(double xy) : this(xy, xy); // Generative, named, forwarding, const.
    }
    

    转发工厂构造函数将其参数转发给其他构造函数。例子:

    abstract class Point {
      double get x;
      double get y;
      const factory Point(this.x, this.y) = _Point;  // Factory, unnamed, forwarding, const.
    }
    class _Point implements Point {
      final double x, y;
      const _Point(this.x, this.y); // Generative, unnamed, non-forwarding, const.
    }
    

    最后,构造函数可以 const 不管怎样。 一个常量生成构造函数要么转发给另一个常量生成构造函数,然后 : this(...) 参数必须是潜在的常量表达式,或者是非转发的,然后所有初始值设定项表达式必须是潜在的常量表达式,并且不能有正文。 一个const工厂的建设者 正在转发到另一个const构造函数(无论是工厂的还是生成的)。常量构造函数不能有正文,非转发工厂构造函数必须有正文。

      Foo.bar(this.value, int otherValue) : _otherValue = otherValue, super.bar(42) {
        this.doSomething();
      }
    

    非重定向工厂构造函数是唯一可以使用的地方 初始化窗体 (窗体的参数 this.value ). 初始化器列表可以初始化在同一个类中声明的实例变量,但是如果没有实例变量,则可以明显地为空。最后的超级调用必须调用超类的生成构造函数,但默认为 super() 如果省略。主体是新对象第一个可用的位置(如图所示) this ; )如果是空的。这就是为什么最简单的构造函数 Foo(); (这也是 如果没有声明其他构造函数,则得到的构造函数)。