5

https://www.dartlang.org/guides/language/language-tour#final-and-const

In Language Tour of Dart docs, it says "Note: Instance variables can be final but not const. Final instance variables must be initialized before the constructor body starts — at the variable declaration, by a constructor parameter, or in the constructor’s initializer list."

But it's possible to make a constant object using a constant constructor. Why is it not possible to declare a constant variable as a member variable in Dart?

BuyBack
  • 51
  • 1
  • 2

4 Answers4

5

const means compile-time constant.
If you need to create an instance at runtime to create the value, it's not a compile-time constant anymore and therefore its members also can't be const.

Static members do not need an instance to be created and can therefore be constant no matter if the class has a const constructor or if it is used with const or not.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    But why final fields of const instances are not assignable to const too? They _are_ compile time constant – Rémi Rousselet Apr 02 '19 at 08:22
  • 1
    Getter access is not valid in const expressions. Fields and getter is equivalent is Dart for the user of a class. You can change a field to a getter without breaking users of your class. If field access would be allowed, getter access has to as well. That would break that concept in Dart. – Günter Zöchbauer Apr 02 '19 at 08:26
  • Why is the analyzer able to read properties of a constant object then? Because if the getter is runtime only, a code-generator shouldn't be able to know what's inside. – Rémi Rousselet Apr 02 '19 at 08:35
  • Good question, but I don't know much about the Analyser. – Günter Zöchbauer Apr 02 '19 at 08:52
  • It's silly that the compiler can't figure out the instance is set once only and promote it to compile time. – RichieHH Jul 24 '23 at 13:53
4

Why is it not possible to declare a constant variable as a member variable in Dart?

Lets first define what member or instance variables are. Instance variables are basically things that define properties of an object. So, an object of a Car class made like Car(name: "Mercedeces", price: 500000) will have different member property values than Car(name: "Toyota", price: 10000).

Now having an instance variable as final basically means that once you define a Car object with name Mercedes you absolutely can not change the name of the object at run time. You suppose need a Car with name BMW so make a new object. This makes sense when allowing instance properties as final.

Now, lets look at const. const are compile time constants. Suppose you are allowed to define the name instance variable of Car as const. Doing this basically means, no matter how many instances you create of the Car object, all of the names will be the same and just like final members you cannot change it. The first part sounds odd. Not all cars will have the same name, that is contradictory to what instance or object of a class means. A object property may be immutable, using final but definitely will not have the same values. You would want to be able to makes instances of Mercedes sometimes and BMW sometimes. So, it makes no sense to make a instance property as const. This is why dart doesn't allow const without a static keyword. You need a static keyword beside a const property inside a class because only then it conforms to the definition of instance properties.

Shababb Karim
  • 3,614
  • 1
  • 22
  • 35
  • 1
    The part I'm confused is, in C++ you can declare a const variable in a class, and that variable can have different values in different instances. The main conditions for a variable to be const are 1. it should be initialized on the same line and can't be re-assigned 2. it contains a compile time constant value. If only these conditions are to be satisfied, there is no actual reason for a const variable to have the same value in all instances. It seems to me Dart syntax doesn't distinguish const from static const. – BuyBack Apr 04 '19 at 02:49
2

You can have constants inside a class but they will not be classified as instance variables. The key relies on the difference between final and const, you can't have const instance variables because constants are not variables.

  • final variables can only be assigned once but this happens at runtime.
  • the const keyword indicates a compile time constant.

Constants inside classes must be static though, so you could write something like:

class MyClass {
    static const kMyConstant = 100;

    void talk() {
        print('My constant is $kMyConstant');
    }
}

This is perfectly valid in dart.

Mariano Uvalle
  • 705
  • 4
  • 10
2

Simply because if you want something const, it has to be done in compile-time, so either:

  1. The entire instance is const: This is done by const-constructor.
  2. The entire instance is not const.

You mark only one field const is meaningless.

E.g. const means "only one" there: you can use Car class to create a lot of Car-instances, then you say your wheel is const, so you share a wheel among all Car?

But you can make Car teslaCar = Car.fromModel(type: "Tesla") get the only one compile-time model const Car.

NeoZoom.lua
  • 2,269
  • 4
  • 30
  • 64