Skip to content

Variables

Flutter is statically type, therefore, all types are evaluated at compile time, this can be Explicitly defined as:

String text = "hello";
int number = 22;

However, Flutter also provides a implicit declaration (var) that can be determined by compiler, an Example being:

var text = "hello";
var number = 22;

Another way of implicit definition is declaring as Object class, since all types in Dart inherits From the Object type, implicit definitions can be written as:

Object text = "hello";
Object number = 22;

One exception is that Flutter also allow dynamic typing, if a declarator dynamic is used, the Evaluation will happen at runtime:

dynamic text = "hello";
dynamic number = 22;
### Mutation Specifier

Variables with final specifier is instantiated once and will prevent mutation afterwards, The instantiation is performed when calling the constructor:

class Foo extends StatelessWidget {
const Foo({
super.key,
required this.text,
required this.number
});
final String text;
final bool number;
}

In the example, both text and number are required to be instantiated during the constructor Call:

void main(){
Foo body = Foo(
text: "hello",
number: 22
)
}

After the instantiation, the variables cannot be mutated, upon mutation, a compile time error will Appear.

Variables with const specifier are required to be evaluated at compile time, meaning the value Cannot be mutated by any event in runtime including a constructor call.

const String text = "hello";
const int number = 22;

Variables are required to be defined at declaration by default, to enable the option for the Variable to be nullThe ? specifier should be used:

String? text;
int? number;

When a variable is null, and the compile time null check for the variable is disabled by the Nullable specifier, null will be treated as a absense of value and therefore can perform Instantiation checks with null:

int? value; // initialized to "null'
// This null-check ensures that 'value' is not 'null'
if (value != null) {
doSomething(value);
}

Assigning nullable values to non-nullable types will generate a compile time error:

String? world(){
return "hello"
}
void main(){
String? text = world();
String text = world(); // compile time error
}

To allow top-level variables and class variables to be initialize separately to their declaration, The late specifier can be used, an example being:

late String text;
void main(){
text = "hello";
print(text);
}

When accessing a late specified variable without instantiation at runtime, a runtime exception Will be thrown (runtime error):

late String text;
void main(){
print(text); // Runtime exception
text = "hello";
}
#### String Literals

Only one String type exists in Dart, StringWhich holds a sequence of characters specify in UTF-16 code. Within String declarations ""``${ \\ expression } can be declared, and any Expression that can evaluates to String can be placed within. A raw String can be created with Declarator r infront of the string:

As with many other languages, concatenation with + cause a new String instance to be created, Writing to a StringBuffer will prevent this process, therefore its recommended, an example is Shown bellow.

Instead of:

var text = "';
for(var i = 0; i < 100000; ++i) {
text += '$i, \n';
}
print(text);

Using StringBuffer:

final text = StringBuffer();
for(var i = 0; i < 100000; ++i) {
text.writeln('$i, ');
}
print(text.toString());

Dart booleans are still interfaces that inherits ObjectAnd only alow true and false Assignment. 1 and 0 are not allowed.

Dart enum are non-inheritable classes that holds a fixed number of constant values. All enum Extends from the Enum class automatically when declared. Differ from enums in other languages like C++, Dart enums can hold fields, methods and const constructors. An example of enum:

Records (Dart 3.0+) are an anonymous immutable aggregate type — a composite of named positional and Named fields. They are value types with structural equality, similar to C++ std::tuple with named Elements, or Kotlin data classes.

// Positional fields (accessed by position: $1, $2, etc.)
var point = (10, 20);
print(point.$1); // 10
print(point.$2); // 20
// Named fields
var user = (name: "Wyatt'', age: 22);
print(user.name); // Wyatt
print(user.age); // 22
// Mixed positional and named
var record = ("hello', count: 42, pi: 3.14);
print(record.$1); // 'hello'
print(record.count); // 42
// Typed records
(int, String) pair = (1, 'a');
({String name, int age}) person = (name: "Wyatt'', age: 22);
// Records in function returns (replacing the need for custom classes)
(int min, int max) getBounds(List<int> data) {
return (data.reduce(min), data.reduce(max));
}
var (lo, hi) = getBounds([3, 1, 4, 1, 5]);