As described in the documentations:
The const keyword isn’t just for declaring constant variables. You can also use it to create constant values, as well as to declare constructors that create constant values. Any variable can have a constant value.
Can someone explain the use of constant values?
This is a simple example which I hope explains clearly:
Start with two variables and a constant.
var foo = [10,11];
var bar = const [20,21];
const baz = [30,31];
Try to modify foo and it succeeds.
foo.add(12); // [10,11,12]
Try to similarly modify bar and there's an error, because even though bar is a variable, its value was declared to be a constant, thus is immutable.
bar.add(22); // ERROR!
Try to reassign bar to a different value. That works since bar itself was not declared as a constant.
bar = [40,41];
Now, try to modify bar's value again and this time it works, since its new value is not a constant.
bar.add(42) // [40,41,42]
Try to modify baz and there's an error, since baz being declared as a constant itself, its value is inherently immutable.
baz.add(32); // ERROR!
Try reassigning baz to a new value and it fails because baz is a constant and can't be reassigned to a new value.
baz = [50,51]; // ERROR!
void main() {
simpleUse();
finalUse();
constUse();
}
simpleUse() {
print("\nsimple declaration");
var x = [10];
print('before: $x');
x = [5];//changing reference allowed
x.add(10);//changing content allowed
print('after: $x');
}
finalUse() {
print("\nfinal declaration");
final x = [10];
print('before: $x');
// x = [10,20]; //nope changing reference is not allowed for final declaration
x.add(20); //changing content is allowed
print('after: $x');
}
constUse() {
print("\nconst declaration");
const x = [10];
print('before: $x');
// x = [10,20]; //nope -> changing reference is not allowed for final declaration
// x.add(20);//nope -> changing content is not allowed
print('after: $x');
}
Also, variables are simple values like x = 10;
values are instances of enums, list, maps, classes, etc.
I want to add, that another point for const is to guarantee your get the same instance of the object each time you construct it with the same parameters:
class Test {
final int value;
const Test(this.value);
}
void main() {
print(Test(5).hashCode == Test(5).hashCode); // false
print((const Test(5)).hashCode == (const Test(5)).hashCode); // true
}
This is the reason why the const constructor can be difficult to make for all objects since your need to make sure the object can be constructed on compile-time. Also, why after creation of the object no internal state can be changed as the previous answer also shows.
Related
What is the difference between the const and final keywords in Dart?
There is a post on dart's website and it explains it pretty well.
Final:
"final" means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
Const:
"const" has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Const objects have a couple of interesting properties and restrictions:
They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.
They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.
They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated.
So, what does this mean?
Const:
If the value you have is computed at runtime (new DateTime.now(), for example), you can not use a const for it. However, if the value is known at compile time (const a = 1;), then you should use const over final. There are 2 other large differences between const and final. Firstly, if you're using const inside a class, you have to declare it as static const rather than just const. Secondly, if you have a const collection, everything inside of that is in const. If you have a final collection, everything inside of that is not final.
Final:
final should be used over const if you don't know the value at compile time, and it will be calculated/grabbed at runtime. If you want an HTTP response that can't be changed, if you want to get something from a database, or if you want to read from a local file, use final. Anything that isn't known at compile time should be final over const.
With all of that being said, both const and final cannot be reassigned, but fields in a final object, as long as they aren't const or final themselves, can be reassigned (unlike const).
Const
Value must be known at compile-time, const birthday = "2008/12/25" Can't be changed after initialized.
Final
Value must be known at run-time, final birthday = getBirthDateFromDB() Can't be changed after initialized.
Consolidated #Meyi and #faisal-naseer answers and Comparing with little programming.
const:
const keyword used to make a variable to store a compile time constant value. Compile time constant value is a value which will be constant while compiling :-)
For example 5 is a compile time constant. While DateTime.now() which is not compile time constant. Because this method will return the time when the line is getting executed at runtime. So we can't assign the DateTime.now() to a const variable.
const a = 5;
// Uncommenting below statement will cause compile time error.
// Because we can't able to assign a runtime value to a const variable
// const b = DateTime.now();
Should be initialized at the same line.
const a = 5;
// Uncommenting below 2 statement will cause compilation error.
// Because const variable must be initialized at the same line.
// const b;
// b = 6;
All statements mentioned below are acceptable.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
Class level const variable should be initialized like below.
Class A {
static const a = 5;
}
Instance level const variable is not possible.
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
The another major use of const is used to make the object immutable. To make a class object immutable we need to use the const keyword with constructor and make all the fields as final like mentioned below.
Class A {
final a, b;
const A(this.a, this.b);
}
void main () {
// There is no way to change a field of object once it's
// initialized.
const immutableObja = const A(5, 6);
// Uncommenting below statement will give compilation error.
// Because you are trying to reinitialize a const variable
// with other value
// immutableObja = const A(7, 9);
// But the below one is not the same. Because we are mentioning objA
// is a variable of a class A. Not const. So we can able to assign
// another object of class A to objA.
A objA = const A(8, 9);
// Below statement is acceptable.
objA = const A(10, 11);
}
we can use const keyword to a list.
const a = const [] - A variable a initialized as const which contains a list of const objects(i.e., The list should contain only compile time constant and immutable objects). So we can't able to assign a with another list.
var a = const [] - A variable a initialized as var which contains a list const objects. So we can able to assign another list to the variable a.
Class A {
final a, b;
const A(this.a, this.b);
}
class B {
B(){ // Doing something }
}
void main() {
const constantListOfInt = const [5, 6, 7,
// Uncommenting below statement give compilation error.
// Because we are trying to add a runtime value
// to a constant list
// DateTime.now().millisecondsSinceEpoch
];
const constantListOfConstantObjA = const [
A(5, 6),
A(55, 88),
A(100, 9),
];
// Uncommenting below 2 statements will give compilation error.
// Because we are trying to reinitialize with a new list.
// constantListOfInt = [8, 9, 10];
// constantListOfConstantObjA = const[A(55, 77)];
// But the following lines are little different. Because we are just
// trying to assign a list of constant values to a variable. Which
// is acceptable
var variableWithConstantList = const [5, 6, 7];
variableWithConstantList = const [10, 11, 15];
var variableOfConstantListOfObjA = const [A(5, 8), A(7, 9), A(10, 4)];
variableWithConstantList = const [A(9, 10)];
}
final:
final keyword also used to make the variable to hold a constant value. Once initialized we can't change the value.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
All statements mentioned below are acceptable.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// Can't use var along with final keyword. Uncommenting below line cause compilation issue.
// final var c = 6;
Able to assign a runtime value.
// DateTime.now() will return the time when the line is getting
// executed. Which is a runtime value.
final a = DateTime.now();
var b = 5;
final c = b;
Class level final variable must be initialized in the same line.
Class A {
static final a = 5;
static final b = DateTime.now();
}
Instance level final variable must be initialized in the same line or in the constructor initialization. The value will be put into memory when the object is created.
Class A {
final a = 5;
}
// Constructor with a parameter.
Class B {
final b;
B(this.b);
}
// Constructor with multiple parameter.
Class C {
final c;
C(this.c, int d) {
// Do something with d
}
}
void main() {
A objA = new A();
B objB = new B(5);
C objC = new C(5, 6);
}
Assigning a list.
final a = [5, 6, 7, 5.6, A()];
// Uncommenting Below statement will give compilation error.
// Because we are trying to reinitialize the object with another list.
// a = [9.9, 10, B()];
Extending the answer by #Meyi
final variable can only be set once and it is initialized when
accessed.(for example from code section below if you use the value of biggestNumberOndice only then the value will be initialized and memory will be assigned).
const is internally final in nature but the main difference is that
its compile time constant which is initialized during compilation
even if you don't use its value it will get initialized and will take
space in memory.
Variable from classes can be final but not constant and if you want a
constant at class level make it static const.
Code:
void main() {
// final demonstration
final biggestNumberOndice = '6';
// biggestNumberOndice = '8'; // Throws an error for reinitialization
// const
const smallestNumberOnDice = 1;
}
class TestClass {
final biggestNumberOndice = '6';
//const smallestNumberOnDice = 1; //Throws an error
//Error . only static fields can be declared as constants.
static const smallestNumberOnDice = 1;
}
const means its initial value is must be fixed, can not be a dynamic value;
final means its initial value is must be fixed but can be a dynamic value, equal to the var with a fixed value.
code demos
const
void main() {
const sum = 1 + 2;
// ✅ const can not change its value
print("sum = ${sum}");
// ⚠️ Const variables must be initialized with a constant value.
const time = new DateTime.now();
// ❌ Error: New expression is not a constant expression.
print("time = ${time}");
}
final
// new DateTime.now();
// dynamic timestamp
void main() {
final sum = 1 + 2;
// ✅ final can not change its value
print("sum = ${sum}");
final time = new DateTime.now();
// ✅ final === var with fixed value
print("time = ${time}");
}
Screenshots
refs
https://dart.dev/guides/language/language-tour#final-and-const
final and const in dart are confusing to the level we think both of them are the same.
Let's see their differences :
P.S. I included image instead of text as I couldn't tabulate the info
in Stackoverflow .md format easily.
Both final and const prevent a variable from being reassigned (similar to how final works in Java or how const works in JavaScript).
The difference has to do with how memory is allocated. Memory is allocated for a final variable at runtime, and for a const variable at compile-time. The final modifier should be the more commonly used, because many program variables won't need any memory since the program logic won't call for them to be initialized. With a const variable you are basically telling the computer, "Hey, I need memory for this variable up front because I know I'm going to need it."
Thinking of them in this way makes it easier to understand differences in their syntactical usage. Mainly that a final variable may be an instance variable, but a const must be a static variable on a class. This is because instance variables are created at runtime, and const variables--by definition--are not. Thus, const variables on a class must be static, which means simply that a single copy of that variable exists on a class, regardless of whether that class is instantiated.
This video breaks it down fairly simply:
https://www.youtube.com/watch?v=9ZZL3iyf4Vk
This article goes into more depth and explains a very important semantic difference between the two, i.e. final modifies variables and const modifies values, which essentially boils down to only being able to initialize const values which are derivable at compile-time.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
Anything that isn't known at compile time should be final over const.
If you are coming from C++ then const in Dart is constexpr in C++ and final in Dart is const in C++.
The above applies to primitive types only.
However in Dart objects marked final are mutable in terms of it's members.
Simple words:
Const
Value must be known at compile-time, i.e. values coming from internal files.
Sample: API keys, supported languages of your app or any variables in your i.e. helper file, basically anything which you ship with your app.
Final
Value must be known at run-time.
It can be data like above but also i.e. device info which will be checked when the app is starting or data that is loaded from API's or servers when the app starts, but before the app is ready to use i.e. you need to check if the user is logged in or not, your app would load or check a session token from the server.
The answer is in the image itself.
const is a Compile-time constant.
final is a Run-time constant.
All these answers I can describe in a concise way.
const list = [1, 2, 3];
Both variable/identifier & value are const. Like - const list = const [1, 2, 3]
That's why they are not allowed to be re-assigned.
Good fit for global variables.
It is possible to use it as a class variable but have to set static. Like - static const list = [1, 2, 3].
vs:
final list = [1, 2, 3];
Variable/Identifier is const but value is not. Like - const list = [1, 2, 3]
That's why we can perform like - list.add(4)
You can't initialise a const using a final. For example :
final myConst = 1;
const myFinal = 2;
final a = myConst; // possible
final b = myFinal; // possible
const c = myConst; // this is not possible
const d = myFinal; // possible
When to use which keyword?
A simple example for both:
Use final: If you don’t know what it’s value will be at compile-time. For example, when you can need to get data from an API, this happens when running your code.
Use const: If you are sure that a value isn’t going to be changed when running your code. For example, when you declare a sentence that always remains the same.
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
A variable with the final keyword will be initialized at runtime and can only be assigned for a single time.
A variable with the const keyword is initialized at compile-time and is already assigned when at runtime.
Use final: If you don’t know what it’s value will be at compile-time. For example, when you can need to get data from an API, this happens when running your code.
Use const: If you are sure that a value isn’t going to be changed when running your code. For example, when you declare a sentence that always remains the same.
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.
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. :]
According to this article:
As you might know, dynamic (as it is now called) is the stand-in type when a static type annotation is not provided.
So, what is the difference between dynamic and var? When to use?
dynamic is a type underlying all Dart objects. You shouldn't need to explicitly use it in most cases.
var is a keyword, meaning "I don't care to notate what the type is here." Dart will replace the var keyword with the initializer type, or leave it dynamic by default if there is no initializer.
Use var if you expect a variable assignment to change during its lifetime:
var msg = "Hello world.";
msg = "Hello world again.";
Use final if you expect a variable assignment to remain the same during its lifetime:
final msg = "Hello world.";
Using final (liberally) will help you catch situations where you accidentally change the assignment of a variable when you didn't mean to.
Note that there is a fine distinction between final and const when it comes to objects. final does not necessarily make the object itself immutable, whereas const does:
// can add/remove from this list, but cannot assign a new list to fruit.
final fruit = ["apple", "pear", "orange"];
fruit.add("grape");
// cannot mutate the list or assign a new list to cars.
final cars = const ["Honda", "Toyota", "Ford"];
// const requires a constant assignment, whereas final will accept both:
const names = const ["John", "Jane", "Jack"];
dynamic: can change TYPE of the variable, & can change VALUE of the variable later in code.
var: can't change TYPE of the variable, but can change VALUE of the variable later in code.
final: can't change TYPE of the variable, & can't change VALUE of the variable later in code.
dynamic v = 123; // v is of type int.
v = 456; // changing value of v from 123 to 456.
v = 'abc'; // changing type of v from int to String.
var v = 123; // v is of type int.
v = 456; // changing value of v from 123 to 456.
v = 'abc'; // ERROR: can't change type of v from int to String.
final v = 123; // v is of type int.
v = 456; // ERROR: can't change value of v from 123 to 456.
v = 'abc'; // ERROR: can't change type of v from int to String.
try this in DartPad:
void main() {
dynamic x = 'hal';
x = 123;
print(x);
var a = 'hal';
a = 123;
print(a);
}
you can change the type of x, but not a.
var, like final, is used to declare a variable. It is not a type at all.
Dart is smart enough to know the exact type in most situations. For example, the following two statements are equivalent:
String a = "abc"; // type of variable is String
var a = "abc"; // a simple and equivalent (and also recommended) way
// to declare a variable for string types
On the other hand, dynamic is a special type indicating it can be any type (aka class). For example, by casting an object to dynamic, you can invoke any method (assuming there is one).
(foo as dynamic).whatever(); //valid. compiler won't check if whatever() exists
(foo as var).whatever(); //illegal. var is not a type
var a ;
a = 123;
print(a is int);
print(a);
a = 'hal';
print(a is String);
When defined without initial value, var is dynamic
var b = 321;
print(b is int);
print(b);
//b = 'hal'; //error
print(b is String);
When defined with initial value, var is int in this case.
To clarify some of the previous answers, when you're declaring a variable as dynamic, it's type changes depending on what you assign to it. When you're declaring a var, the type is set once it's assigned something, and it cannot be changed after that.
For example, the following code:
dynamic foo = 'foo';
print('foo is ${foo.runtimeType} ($foo)');
foo = 123;
print('foo is ${foo.runtimeType} ($foo)');
will return the following result when run in DartPad:
foo is String (foo)
foo is int (123)
But the following code won't even compile:
var bar = 'bar';
print('bar is ${bar.runtimeType} ($bar)');
bar = 123; // <-- Won't compile, because bar is a String
print('bar is ${bar.runtimeType} ($bar)');
Long story short - use dynamic if you want a non-typed variable, use var when you want a typed variable with whatever type you assign to it.
Looking at the previous answers I hope this can clarify/summarize everything:
There are the keywords var, final, and const. These are to declare a variable (to indicate its existence) (Side note: Declaration vs Initialization)
Then there are types like String, int, List, dynamic, etc. (The type indicates what kind of value the variable should hold, this is for type safety)
Usually, we declare a variable by explicitly stating its type:
String a; // a is now a String type
int b; // b is now an int type
But we can also use the var keyword. By default, this sets the type of the variable to whatever it is initialized with. (This is called type inference)
var a = "hello"; // a is now a String type
var b = 5; // b is now an int type
Now what happens when you try to declare a variable with the var keyword, but don't initialize a value? How is it supposed to infer a type? Well, there is also a type called dynamic. This is different than the usual String or int in the sense that it allows for the variable to be assigned a value of any type (Usually there will be an error).
String a = "hello"; // a is now a String type
// var a = "hello"; // Alternative way; same as the line above because its type is inferred to be String
a = 5 // error: A value of type 'int' can't be assigned to a variable of type 'String'
dynamic b; // b is now a dynamic type
b = "hello"; // still a dynamic type, but now its value is of type String (You can use b.runtimeType to check)
b = 5; // dynamic type, but now its value is of type int
So to address the original confusion regarding the quote from the article,
As you might know, dynamic (as it is now called) is the stand-in type when a static type annotation is not provided.
It just means that if you don't explicitly state its type (you use var to declare a variable) and do so without initialization, it simply infers its type as dynamic:
var b; // b is now a dynamic type, the following will not have any errors.
b = "hello";
b = 5;
b = true;
Other notes:
Not sure why people started talking about final and const, but I think the accepted answer here explains it well if you want to know more.
dynamic a; and var a; is effectively the same: They both declare a variable of dynamic type.
Two ways of checking the type of a variable is using the is operator and using .runtimeType which works differently. See the following example:
dynamic b; // b is now a dynamic type, no value
print(b is dynamic); // true
print(b is Null); // true
print(b is String); // false
print(b is int); // false
print(b.runtimeType); // Null
b = "hello"; // dynamic type, String value
print(b is dynamic); // true
print(b is Null); // false
print(b is String); // true
print(b is int); // false
print(b.runtimeType); // String
b = 5; // dynamic type, int value
print(b is dynamic); // true
print(b is Null); // false
print(b is String); // false
print(b is int); // true
print(b.runtimeType); // int
One of aspect than can consider in comparison dynamic vs var is taking into account behavior when using var declaration with initialization at the same time there is not possibility to change type which in case of dynamic is.
But dynamic vs var is not the question what I would ask.
I would ask more what is difference between dynamic vs Object.
Here is a DO annotate with Object instead of dynamic to indicate any object is allowed.
It is hard to feel it at the beginning, but dynamic I would relate to generic type argument.
Both in dynamic and var,the variable can hold data of any data type, i.e., int , float,string,etc
If a variable is declared as a dynamic and if even initialised, its type can change over time.Try this code in https://dartpad.dev/
void main() {
dynamic x = 'abc';
x = 12345;
print(x);
}
If you declare variable as a var, once assigned type can not change.
void main() {
var x = 'abc';
x = 12345;
print(x);
}
The above code will result in the error stating that A value of type 'int' can't be assigned to a variable of type 'String' - line 3
BUT, if you state a var without initializing, it becomes a dynamic:
void main() {
var x ;
x = 'abc';
x=12345;
print(x);
}
A dynamic variable can change his type and a var type can't be changed.
For example :
var myVar = 'hello';
dynamic myDynamicVar = 'hello';
myVar = 123; // not possible
myDynamicVar = 123; // possible
dynamic is a data type that indicates all data types in dart
var is a variable declaration way like "final" that takes the data type of its value
If you use var you can't change the data type of the variable. But if you use dynamic you can change it freely.
for ex.
dynamic x = 12; // type: integer
x= "Hello world"; // type: string
This will work with no issues if you do the same using var instead of dynamic you will get an error since you can't change the data type because it is automatically assigned to the variable when initialized.
dynamic: can change the TYPE of the variable, & can change the VALUE of the variable later in the code.
var: can't change the TYPE of the variable, but can change the VALUE of the variable later in code
I just want have a final List with colors :
final List<String> COLORS = ['#cefbe4', '#81ec72', '#5cd646'];
final num MAX = 90;
class Square {
// ...
It's ok for MAX but it does not compile for list :
Initializer must be a compile time constant
I also tried :
static final num MAX = 90;
class Square {
final List<String> COLORS = ['#cefbe4', '#81ec72', '#5cd646'];
New error : "initializer must be a compile time constant"
The only solution, I found is to initialise in constructor...
I don't like this solution : I don't want a list instance by Square object.
How can I do ?
I don't get the same errors as you. In the first case I get a compile time warning "Expected constant expression" and in the second case another compile-time warning and a runtime error. Try the latest SDK which you can find here.
static final num MAX = 90;
class Square {
final List<String> COLORS = ['#cefbe4', '#81ec72', '#5cd646'];
In this case static it doesn't make any sense because static denotes class variables which are the same for all instantiated objects of the same class. And in this case MAX is outside a class boundary. Hence a runtime error is shown and a compile time warning ("Top-level field cannot be static").
I guess both MAX and COLORS are supposed to be the same for all instances of the Square class. So it makes sense to do this:
class Square {
static final List<String> COLORS = const ['#cefbe4', '#81ec72', '#5cd646'];
static final num MAX = 90;
}
The list itself is the part that is final, not the contents. The contents inside a final list can still be added and removed.
final List<String> COLOURS = new ArrayList<String>();
This would create your list. The actual filling of the list would be done in the constructor, or for that matter anywhere in your code.
It would be more appropriate to use an enum for this in my opinion.
Its a little tricky to search for 'var:*' because most search engines wont find it.
I'm not clear exactly what var:* means, compared to say var:Object
I thought it would let me set arbitrary properties on an object like :
var x:* = myObject;
x.nonExistantProperty = "123";
but this gives me an error :
Property nonExistantProperty not found on x
What does * mean exactly?
Edit: I fixed the original var:* to the correct var x:*. Lost my internet connection
Expanding on the other answers, declaring something with type asterisk is exactly the same as leaving it untyped.
var x:* = {};
var y = {}; // equivalent
However, the question of whether you are allowed to assign non-existant properties to objects has nothing to do with the type of the reference, and is determined by whether or not the object is an instance of a dynamic class.
For example, since Object is dynamic and String is not:
var o:Object = {};
o.foo = 1; // fine
var a:* = o;
a.bar = 1; // again, fine
var s:String = "";
s.foo = 1; // compile-time error
var b:* = s;
b.bar = 1; // run-time error
Note how you can always assign new properties to the object, regardless of what kind of reference you use. Likewise, you can never assign new properties to the String, but if you use a typed reference then this will be caught by the compiler, and with an untyped reference the compiler doesn't know whether b is dynamic or not, so the error occurs at runtime.
Incidentally, doc reference on type-asterisk can be found here:
http://livedocs.adobe.com/labs/air/1/aslr/specialTypes.html#*
(The markup engine refuses to linkify that, because of the asterisk.)
It's a way of specifying an untyped variable so that you can basically assign any type to it. The code
var x:* = oneTypeObject;
creates the variable x then assigns the oneTypeObject variable to it. You can assign an entirely different type to it as well as follows:
var x:* = anotherTypeObject;
However, you still can't arbitrarily set or access properties; they have to exist in the underlying type (of either oneTypeObject or anotherTypeObject).
Both types may have identically named properties which means you can access or set that property in x without having to concern yourself with the underlying type.
It's the "untyped" type. It just means that the variable can be of any type. Basically the same effect as using this:
var x = myObject;
It means that the type is not specified and can be used with any type. However, you can't set random properties on it. It will behave like whatever type you set it to. The exact syntax is:
var x:*;
As they said before, it's untyped, so it may hold any kind of data. However, you cannot treat it as such in operations. For example, this is valid code:
var untyped:* = functionThatReturnsSomeValue();
But if you go one step farther, you have to watch out or you might get bitten:
var name:String = untyped.name;
Now, if the object returned by that function happens to be an object with a field with an id of "name," you are in the clear. However, unless you know for sure that this is the case, it's better to use typed objects. In this way, the compiler will alert you if you do something that might throw an error at runtime:
(elsewhere)
public class TypedObject()
{
public var name:String = "";
}
(and the code at hand)
var typed:TypedObject = functionThatReturnsTypedObject();
var name:String = typed.name;