Dart 笔记
Miscellaneous
- Everything in a variable is an object (except for
null
in null safety) - Can specify dart version in
pubspec.yaml
. One sdk supports multiple language versions1
2environment:
sdk: ">=2.15.1 <3.0.0" _
: visible only inside library
Sound null safety
- All types are non-nullable by default
- use
?
to denote nullable variables1
2int? a = null;
List<String?> listOfNullableStrings = ['one', null]; - use
!
to assert non-null1
int c = couldReturnNullButDoesnt()!.abs();
late
: Tell Dart that a non-null value will be assigned before using the variable1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Meal {
late String _description;
set description(String desc) {
_description = 'Meal description: $desc';
}
String get description => _description;
}
void main() {
final myMeal = Meal();
myMeal.description = 'Feijoada!';
print(myMeal.description);
}
Variable
- All variables stores references (including numbers)
- Default value of nullable variables are
null
- Top-level variables & class variables &
late
variables are lazily initialized final
vsconst
final
: set only onceconst
: compile-time constants (not immutable)
Types
Number
int
anddouble
num
, for bothdouble.parse('1.2')
1.toString()
String
- single or double quotes
- String interpolation
'$variable'
or'${expression}'
- Compare string content:
==
- Concat:
+
or adjacent string literal1
2print('Str'
'ing' == 'Str' + 'ing'); // true - Multiline string: triple quotes
- Raw string (no escape):
r'This is a raw string with \n'
Booleans and some logic check
1 | print(''.isEmpty); |
Lists
Literal:
[1, 2, 3]
Compile-time constant:
var a = const [''];
Spread operator
1
2var list1 = [1, 2, 3];
var list2 = [0, ...list1]; // [0, 1, 2, 3]Null-aware spread:
1
2var list1;
var list2 = [0, ...?list1]; // [0]Collection if
1
var list = [1, 2, if (flag) 3];
Collection for
1
2
3
4
5
6var list1 = [1, 2, 3];
var list2 = [
'obj1',
for (var i in list1) 'obj${i + 1}'
];
// ['obj1', 'obj2', 'obj3', 'obj4']
Sets, Maps, etc
TODO
Functions
Functions are also object with type Function
.
Arrow syntax
=> expr
: {return expr;}
Parameter
- positional parameter
use[]
for optional positional - named parameter
- Define:
{Type name}
- Call:
name: value
- can be marked as
required
- Define:
- Default value
Use= value
. The value must be compile-time constant.
1 | void test(String pos, {String? name1, required String name2}) { |
Main function
- Return type:
void
1
2
3void main() {
} - optional
List<String>
parameter1
2
3void main(List<String> arguments) {
print(arguments);
}
Anonymous function
1 | var func1 = (String arg1) { |
Lexical scope
Scope of variables is defined statically by layout (curly bracket {}
).
Lexical closure
A closure is a function object that has access to variables in its lexical scope.
1 | Function func (List l) { |
Operators
Arithmetic
+
,-
,-expr
(negation),*
,%
/
division~/
integer dividion++var
,--var
,var++
,var--
Equality & Relational
==
: Test equalityx == y
invokes==
method onx
with arguemnty
(when both non-null).
Useidentical(a, b)
to check whethera
andb
refer to the same object.!=
,>
,<
,>=
,<=
Type test
as
: type castis
: test object against a typeis!
: notis
Assignment
=
,op=
??=
assign only if null; otherwise keep original value
Logical
!
,||
,&&
Bitwise & Shift
&
,|
,^
(XOR),~
>>
,<<
,>>>
(unsigned)
Conditional
cond ? expr1 : expr2
expr1 ?? expr2
: if expr1 is non-null
Cascade notation
..
: Used after an object for chain operation.1
2
3
4var paint = Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..strokeWidth = 5.0;is equavalent to:
1
2
3
4var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;?..
: Applied on the first operation => only when not null.
Others
()
[]
,?[]
(null-aware): subscript.
,?.
(null-aware): member access
Control flow
If-Else
1 | if () { |
For loop
- Standard for loop
1
2
3for (var i = 0; i < 5; i++) {
} - Closures
Closures inside of Dart’s for loops capture the value of the index.1
2
3
4
5
6
7
8var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
// This will print
// 0
// 1 - Iterable
1
2
3
4
5// for-in
var l = [1, 2, 3];
for (final n in l) {
print(n);
}1
2
3// forEach
var l = [1, 2, 3];
l.forEach(print);
While
while () {}
& do {} while ();
Switch
- Compare integer, string or compile constants with
==
, of same class - Each
case
clause can either be empty or end with a keyword (break
,continue
,throw
,return
default
- Use
continue
and label to fallback1
2
3
4
5
6
7
8
9
10
11switch() {
case 1:
executeSomething();
continue myLabel;
myLabel:
case 2:
executeSomething();
break;
default:
break;
} - A
case
clause has its local variables
Exceptions
Throw
- All non-null object can be throwed
- Usually throw
Exception
orError
Catch
1 | try { |
Use rethrow
to allow exception to propagate
Finally
try {} finally {}
Run no matter an exception occurs.
Classes
1 | class Point { |
Using class members
1 | int? a = 1; |
Constructors
- Use constructors
1
2
3
4
5
6
7
8
9
10var p = Point();
// Or
var p2 = new Point();
// Constant constructors
var p3 = const ImmutablePoint(0, 1);
const p4 = ImmutablePoint(0, 1);
var p5 = ImmutablePoint(0, 1);
// Constants share the same instance
assert(identical(p3, p4));
assert(!identical(p4, p5)); - Define constructors
- Generative constructor
1
2
3
4
5
6
7
8
9class Point {
double x = 0;
double y = 0;
Point(double x, double y) {
this.x = x;
this.y = y;
}
} - Syntax sugar for assigning arguments to instance variables
1
2
3
4
5
6
7class Point {
double x;
double y;
// Note that the assignment is before constructor body runs,
// so x and y can be uninitialized when declaring;
Point(this.x, this.y);
} - Default constructor
No argument and invokes the no-argument constructor in the super class. - Constructors are not inherited
- Initializer list
Initialize instance variables before constructor body runs. Might be useful to initialize final instance variables.
The right side of initialiers doesn’t have access tothis
.1
2
3
4
5
6
7
8
9
10class Point {
final double x;
final double y;
Point(double x, double y)
: x = x,
y = y {
print('Created new point.');
}
} - Invoking a non-default superclass constructor
1
2
3
4Point(String data)
: super.someConstructor(data) {
print('Created');
} - Named constructor
1
2
3Point.origin()
: x = 0,
y = 0; - Redirecting constructor
1
2
3
4
5
6
7class Point {
double x, y;
Point(this.x, this.y);
Point.onXAxis(double x) : this(x, 0);
} - Constant constructors
- All instance variables must be final
- Use
const
before constructors - Constant constructors cannot have body
- Example:
1
2
3
4class ImmutablePoint {
final double x, y;
const ImmutablePoint(this.x, this.y);
}
- Factory constructors
Usefactory
keyword for constructors that don’t always create a new instance.
- Generative constructor
TODO
Generics, TODO
TODO