static constructor in Dart
Asked Answered
A

8

17

How to write static constructor in Dart?

class Generator
{
   static List<Type> typesList = [];

   //static
   //{ /*static initializations*/}

}
Apophyllite answered 19/1, 2020 at 12:9 Comment(0)
G
16

There is no such thing as a static constructor in Dart. Named constructors such as Shape.circle() are achieved by something like

class A {
  A() {
    print('default constructor');
  }
  A.named() {
    print('named constructor');
  }
}

void main() {
  A();
  A.named();
}

You might also be interested in this factory constructors question

Update: A couple of static initializer work-arounds

class A {
  static const List<Type> typesList = [];
  A() {
    if (typesList.isEmpty) {
      // initialization...
    }
  }
}

Or the static stuff can be moved out of the class if it isn't meant to be accessed by users of the class.

const List<Type> _typesList = [];
void _initTypes() {}

class A {
  A() {
    if (_typesList.isEmpty) _initTypes();
  }
}
Genia answered 19/1, 2020 at 14:39 Comment(4)
thanks Jacob. it seems that Dart is still in development stage,, lacking features what i found in java, is an unpleasing experience, or may by i am very new to Dart...Apophyllite
@arif Dart is pretty mature imo. It doesn't have static initializer blocks like Java, but there are other ways of achieving the same thing. In my experience it can do everything Java can, and is usually more concise. I mean there are differences, nested classes are not supported for example.Genia
When the other ways include things like running code generators before building the program, it's not quite as having the same features. Though I suppose some of that is to achieve some ahead of time compilation advantages. A class doesn't get "loaded" in release dart code. Similarly if you make a global variable, it might not get initialized before it's accessed, so it doesn't seem to be possible to create a system where at runtime the 'class' registers itself to another class as existing(or not) without generated code.Tasset
One reason to not allow this might be avoiding 'static initialization order fiasco' (dependency of a static initializer on another static initializer where the order of initialization is not guaranteed). C++ is prone to this but also Java araccording to https://mcmap.net/q/744458/-does-java-have-the-static-order-initialisation-fiasco.Praetor
A
8

You can initialize static members by calling the class.member directly, inside the constructor:

class A {
  static int a;
  static int b;

  A(int a, int b) {
    A.a ??= a; ///by using the null-equals operator, you ensure this can only be set once
    A.b ??= b;
  }
}


main(){
  A(5,10);
  A(2,4);
  assert(A.a == 5);
  assert(A.b == 10);
}
Alcus answered 19/1, 2020 at 22:20 Comment(2)
thanks E_C. Dart should provide some way. This approach is instance dependent.Apophyllite
This is true. However, due to the nature of static members, it doesn’t matter much, as you can see in my example, even though there are 2 instances, only the first made a difference. But, as Jacob alluded to, factory constructor’s seem to be what you are looking for. They do not need to create a new instance. Also, constant constructor’s will only ever create one instance. Check out : dart.dev/guides/language/language-tour#using-constructors and dart.dev/guides/language/language-tour#constant-constructorsAlcus
U
2

Inspired by @Mahmoud salah eldien saber answer Create a singleton, and static variable reference to the singleton variable

void main() {
  
  print('${Singleton.add()}');
  print('${Singleton.add()}');
  print('${Singleton.add()}');
  print('${Singleton.add()}');     
}

class Singleton {
  Singleton();
    
  //static
  static List<int> typeList = Singleton.internal()._typeList;
  static List<int> add() {
    typeList.add(1);
    return typeList;
  }  
  List<int> _typeList = [];
  factory Singleton.internal() {  
    var s = Singleton();
    for(int i = 0 ; i < 5; i++ ) {
      s._typeList.add(2);
    }   
    return s;
  }    
   
}

I also want to find a official answer for this question.

Unbeknown answered 19/4, 2021 at 3:1 Comment(0)
A
1

Static variable declarations are initialized lazily to avoid costly initialization (and attendant slowness) at program startup.. The first time a static variable v is read, it is set to the result of evaluating its initializer.

https://groups.google.com/a/dartlang.org/forum/#!topic/misc/dKurFjODRXQ

Apophyllite answered 23/1, 2020 at 5:39 Comment(0)
M
1

One of the workarounds to initialize static variables could be to use ".." (called "cascade") operator. This workaround doesn't require object instance. More about cascade operator: https://dart.dev/guides/language/language-tour#cascade-notation .

Example:

static List firstList = [ 'hello', 12, 'goodbye'];

static List dummyObjects = List()
    ..addAll(firstList)
    ..add('another String value')
    ..add('and one more')
    ..add(Object())
    ..removeWhere((o) => o is! String)
;

(So dummyObjects is initialized only with objects that are of type String because all others discarded.)

Morningglory answered 23/8, 2020 at 20:48 Comment(0)
V
1

static initialization block

In Dart there is no equivalent to the Java static initialization block.
However, an easy workaround for most cases is extracting the static initialization logic to a static function.

class Dummy {
  static final Map<int, String> someValues = _createSomeValues();

  static Map<int, String> _createSomeValues() {
    Map<int, String> someValues = {};
    for (var i = 0; i <= 10; i++) {
      someValues[i] = "$i";
    }
    return someValues;
  }
}

Note that the static variable is initialized lazily as described in https://groups.google.com/a/dartlang.org/forum/#!topic/misc/dKurFjODRXQ. However, this behavior should never impact you with normal/clean code.

static method as factory

If you meant named constructors by 'static constructor' take a look at the following answer: https://mcmap.net/q/697604/-static-constructor-in-dart

Vasiliki answered 8/3, 2022 at 0:22 Comment(0)
D
0

To create static (constuctor or class) it's very easy in dart, just create static vaiable in this class and give it object from the same class:

class A {
  static var instance = A();
  static List<int> typesList = [];
  A() {
    print('Call constructor to create object');
  }
  List<int> add() {
    typesList.add(1);
    return typesList;
  }
}

void main() {
  print(A.instance.add());
  print(A.instance.add());
  print(A.instance.add());
  print(A.instance.add());
}
Directrix answered 6/11, 2020 at 9:10 Comment(0)
I
0

You could use a static method like this:

class A {
  A() {
     print('normal constructor');
  }

  static A fromValue(String value){
     ... //use your value
     return A();
  }


}

void main() {
  final a = A.fromValue('myValue');
}
Incidentally answered 30/6, 2023 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.