Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

flutter - Dart assigning to variable right away or in constructor?

In Dart, is there a difference in assigning values right away vs in constructor like in Java?

class Example {
    int x = 3;
}

vs

class Example {
    int x;
    Example() {
        x = 3;
    }
}

I ask because when I was using Flutter and tried to assign a Function that uses setState to a variable, it was not possible with the former method but possible with the latter.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your trivial case, it doesn't matter.

In general, you can initialize instance variables in a few ways:

Inline (field initializers)

class Example1 {
  T x = value;
}

Advantages:

  • Direct, concise.
  • Member will be initialized in all constructors.
  • Can be used to initialize final or non-nullable members.
  • Member is initialized before invoking base class constructors, which is important when the base class constructor calls member functions that are overridden by the derived class.

Disadvantages:

Initializer list

class Example2 {
  T x;

  Example2() : x = value;
}

Advantages:

  • Can be used to initialize final or non-nullable members.
  • Member is initialized before invoking base class constructors, which is important when the base class constructor calls member functions that are overridden by the derived class.
  • Can utilize construction arguments.
  • The initialized variable always refers to a member variable, never to a constructor parameter.

Disadvantages:

  • If the class has multiple constructors, initialization would need to be duplicated, or constructors should redirect to a common constructor.
  • Cannot depend on this since the initialization occurs before this becomes valid (i.e., cannot depend on other instance members).
  • Can initialize only members of the enclosing class. Because initializer lists are executed before invoking base class constructors, they cannot set base class members.

Constructor body

class Example3 {
  T x;

  Example3() {
    x = value;
  } 
}

Advantages:

  • Can utilize construction arguments.
  • Can be used to perform more complicated initialization, such as cases where the member cannot be initialized via a single expression.
  • Can use this (i.e., can use other instance members).
  • Can be used to set base class members.

Disadvantages:

  • Cannot be used to initialize final nor non-nullable members.
  • If the class has multiple constructors, initialization would need to be duplicated or initialization code would need to be refactored out (such as, but not limited to, redirecting to a common constructor).
  • Member is initialized after invoking base class constructors.
  • If the constructor has a parameter that shadows a member variable, it's easy to accidentally refer to the parameter instead of the member. (See https://github.com/dart-lang/linter/issues/2552 for details.)

There probably are some points I'm forgetting, but I think that should cover the main ones.

Direct, inline initialization occurs first, then initialization lists, then constructor bodies. Also see Difference between assigning the values in parameter list and initialiser list which explains why this becomes valid only for the later stages of object initialization.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...