I have looked at some other similar questions on SO, but they don't appear to address the following specifically.
What I want to achieve is to have compile-time constants that cannot be altered.
I have a program which I reorganized a little in order to de-clutter. The program had some const declarations prior to "main()". I moved these to a class, however it required that I declare them as "static const". I then thought, ok those other "const" declarations prior to "main()" should probably also be "static const". However when I attempted that, the Editor advised "Top-level declarations cannot be declared to be 'static'". EG.
static const int I_CORRECT_YN = 12; // prompt nr.
So, I am a little confused. I thought that a "const" was static. Why do I have to declare "static" in the class? Why can't I declare a "top level" const as "static"? Also, what is the difference between:
static const int I_CORRECT_YN = 12;
const int I_CORRECT_YN = 12;
static final int I_CORRECT_YN = 12;
final int I_CORRECT_YN = 12; ?
What is the best or only way to declare compile-time values that cannot be altered?
I guess I am looking at the literal meaning, but I presume there is a more complex meaning.
You have to declare it as static const rather than just const . static , final , and const mean entirely distinct things in Dart: static means a member is available on the class itself instead of on instances of the class. That's all it means, and it isn't used for anything else. static modifies members.
The only difference between final and const is that the const makes the variable constant from compile-time only. Using const on an object, makes the object's entire deep state strictly fixed at compile-time and that the object with this state will be considered frozen and completely immutable.
Dart has the concept of compile-time constants. A compile-time constant is parsed and created at compile time, and canonicalized. For example, here is a const constructor for Point: class Point { final num x, y; const Point(this.x, this.y); }
In dart, the final keyword is used to define immutable constants or objects. It is a runtime constant.
Why do I have to declare "static" in the class?
Because instance variables/methods can't be const
. This would mean their value could be different per instance, which can't be the case for compile-time constants. (Source)
Why can't I declare a "top level" const as "static"?
The static
modifier marks variables/methods as class-wide (same value for every instance of the class). Top-level stuff is application-wide and doesn't belong to any class, so marking them as class-wide doesn't make any sense and is not allowed. (Source)
What is the best or only way to declare compile-time values that cannot be altered?
You are already doing it - add static
when defining class constants. Don't add it when defining top-level constants. Also, use const
. final
vars aren't compile-time values.
What is the difference between [source code with different constant definitions omitted]
static const
and const
is the pretty much the same, usage depends on context.
The difference between const
and final
is that const
are compile-time constants - they can only be initialized using literal values (or expressions constisting of operators and literal values) and can't be changed. final
variables also can't be changed after being initialized, but they are basically normal variables. This means any kind of expression can be used, and the value can be a different one for every class instance:
import "dart:math";
Random r = new Random();
int getFinalValue() {
return new Random().nextInt(100);
}
class Test {
// final variable per instance.
final int FOO = getFinalValue();
// final variable per class. "const" wouldn't work here, getFinalValue() is no literal
static final int BAR = getFinalValue();
}
// final top-level variable
final int BAZ = getFinalValue();
// again, this doesn't work, because static top-level elements don't make sense
// static final int WAT = getFinalValue();
void main() {
Test a = new Test();
print(Test.BAR);
print(BAZ); // different from Test.BAR
print(a.FOO);
a = new Test();
print(Test.BAR); // same as before
print(BAZ); // same as before
print(a.FOO); // not the same as before, because it is another instance,
// initialized with another value
// but this would still be a syntax error, because the variable is final.
// a.FOO = 42;
}
I hope this helped, and I didn't descibe it too confusing. :]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With