Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between constructor and initializer list in Dart?

Tags:

dart

Problem

The output of the following two codes are the same, but what is the essential difference?

A Tour of the Dart Language - Initializer list

import 'dart:math';

class Point {
  final num x;
  final num y;
  final num distanceFromOrigin;

  Point(x, y)
      : x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}

main() {
  var p = Point(3, 4);
  print(p.distanceFromOrigin);
}

My code

  Point(this.x, this.y)
      : distanceFromOrigin = sqrt(x * x + y * y);

Both Outputs are the same 5.

Question

  • How should I use constructor and initializer list properly?

Development Environment

  • Dart 2
  • DartPad

Best regards,

like image 925
RyosukeOK Avatar asked Aug 25 '18 01:08

RyosukeOK


People also ask

What is initializer list in Dart?

An initializer list allows you to assign properties to a new instance variables before the constructor body runs, but after creation. This is handy when you want to set a final variables value, but the value isn't a compile-time constant.

What is constructor in Dart?

A constructor is a special function of the class that is responsible for initializing the variables of the class. Dart defines a constructor with the same name as that of the class. A constructor is a function and hence can be parameterized. However, unlike a function, constructors cannot have a return type.

What is initializer list in a constructor?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

Does initializer list run before constructor?

As already answered, initialization lists get completely executed before entering the constructor block. So it is completely safe to use (initialized) members in the constructor body.


2 Answers

There is no difference, the result will be the same except that you can take advantage of different type of constructors.

In the case you don't want to expose your variables defined in Point and your mark those as private, the initializer would be a good option.

    class Point {
      final num _x;
      final num _y;
      final num _distanceFromOrigin;

      Point(x, y)
          : _x = x,
            _y = y,
            _distanceFromOrigin = sqrt(x * x + y * y);
    }

Also take a look to the constructor with optional parameters or factory constructors.

like image 122
diegoveloper Avatar answered Oct 20 '22 01:10

diegoveloper


Whether by train or pram, once you reach the station, it makes no "essential" difference if only arriving at the destination matters.

Using "constructor" and "initializer list", you did get the same output, but that example is not the only use case supported by these features in Dart. Moreover, the shorter form (using "constructor" as an alternative to "initializer list") is just a frequent manifestation where Dart provided it as "syntactic sugar":

The pattern of assigning a constructor argument to an instance variable is so common, Dart has syntactic sugar to make it easy:

class Point {
  double x = 0;
  double y = 0;

  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  Point(this.x, this.y);
}


I have used the terms "constructor" and "initializer list" apropos of your question/example, but to clearly mention the differences, I shall be using the following terminology for a broader perspective:

ClassName[.<constructor-name>](<constructor-args>) 
    : <initializer-list> {
  <constructor-body>
}

Until this part of the answer, the focus on "constructor" was largely disregarding the constructor's body, which happened to be the case since that example was probably meant to introduce initializer lists, as evident from the involvement of final members.


Final or Non-nullable Members

Constructor's body cannot be used to initialize non-nullable and/or final members. It could be done

  • at the member declaration site, or
  • directly through the constructor's arguments (using the this. syntactic sugar), or
  • necessarily the initializer list if some calculation is also involved (or using a factory constructor when the initialization logic cannot be handled in the initializer list)
class Demo {
  int x; // non-nullable member
  final int? y; // final member

  // ERROR (observe <constructor-body>'s limitation)
  Demo.constructor1(int x, int y) {
    this.x = x; 
    this.y = y;
  }

  // Allowed
  Demo.constructor2(int x, int y)
      : x = x,
        y = y;

  // Better (observe <constructor-args>'s syntactic sugar)
  Demo.constructor3(this.x, this.y);

  // ERROR
  Demo.constructor4(this.x, this.y = this.x + 1);

  // Allowed (observe <initializer-list>'s rescue)
  Demo.constructor5(this.x) : y = x + 1;
}

Aside, this does not make initializer list a replacement for constructor body since initializer lists are very limited in functionality.


Order of Execution

Another important difference is their order of execution, which could be significant from a design perspective, especially involving inheritance. It is fittingly documented in the language tour:

[...] the order of execution is as follows:

  1. initializer list
  2. superclass’s no-arg constructor
  3. main class’s no-arg constructor

If the superclass doesn’t have an unnamed, no-argument constructor, then you must manually call one of the constructors in the superclass. Specify the superclass constructor after a colon (:), just before the constructor body (if any).

Jamesdlin's comment contains a good summary.



How should I use constructor and initializer list properly?

Keeping the aforementioned differences in mind, "proper" usage objectively abides by such language constraints, but in cases where both the usage is appropriate, I reckon you are correct in utilizing the syntactic sugar for writing idiomatic Dart code unless required otherwise by something akin to an enforced style guide.

like image 26
Ardent Coder Avatar answered Oct 20 '22 00:10

Ardent Coder