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 versionsyamlenvironment: 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 variablesdartint? a = null; List<String?> listOfNullableStrings = ['one', null];
- use
!
to assert non-nulldartint c = couldReturnNullButDoesnt()!.abs();
late
: Tell Dart that a non-null value will be assigned before using the variabledartclass 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 literaldartprint('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
``` dart
print(''.isEmpty);
var a;
print(a == null);
print((0/0).isNaN);
// All true
```
Lists
Literal:
[1, 2, 3]
Compile-time constant:
var a = const [''];
Spread operator
dartvar list1 = [1, 2, 3]; var list2 = [0, ...list1]; // [0, 1, 2, 3]
Null-aware spread:
dartvar list1; var list2 = [0, ...?list1]; // [0]
Collection if
dartvar list = [1, 2, if (flag) 3];
Collection for
dartvar 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.
dart
void test(String pos, {String? name1, required String name2}) {
print('positional: $pos, named: $name1, required named: $name2');
}
void test2(String pos1, [String? pos2 = 'pos2']) {
print('positional: $pos1, optional positional: $pos2');
}
test('1', name2: 'name2');
test2('pos1')
Main function
- Return type:
void
dartvoid main() { }
- optional
List<String>
parameterdartvoid main(List<String> arguments) { print(arguments); }
Anonymous function
dart
var func1 = (String arg1) {
print(arg1);
};
// Or short version
var func2 = (arg1) => print(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.
dart
Function func (List l) {
return () => print(l);
}
void main() {
var l = [1, 2, 3];
var f = func(l);
f(); // [1, 2, 3]
l.add(4);
f(); // [1, 2, 3, 4]
}
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.dartvar paint = Paint() ..color = Colors.black ..strokeCap = StrokeCap.round ..strokeWidth = 5.0;
is equavalent to:
dartvar 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
dart
if () {
} else if () {
} else {
}
For loop
- Standard for loopdart
for (var i = 0; i < 5; i++) { }
- Closures
Closures inside of Dart’s for loops capture the value of the index.dartvar callbacks = []; for (var i = 0; i < 2; i++) { callbacks.add(() => print(i)); } callbacks.forEach((c) => c()); // This will print // 0 // 1
- Iterabledart
// for-in var l = [1, 2, 3]; for (final n in l) { print(n); }
dart// 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 fallbackdartswitch() { 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
dart
try {
executeSomething();
} on ExceptionType catch (e) {
print(e);
} on AnotherType {
print("Exception AnotherType");
} catch (e, s) {
print("Exception $e, stack trace: $s");
}
Use rethrow
to allow exception to propagate
Finally
try {} finally {}
Run no matter an exception occurs.
Classes
dart
class Point {
int x = 0;
int y = 0;
}
Using class members
dart
int? a = 1;
Point? p;
a = p?.x;
assert(a == null);
Constructors
- Use constructorsdart
var 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 constructordart
class 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 variablesdart
class 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
.dartclass 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 constructordart
Point(String data) : super.someConstructor(data) { print('Created'); }
- Named constructordart
Point.origin() : x = 0, y = 0;
- Redirecting constructordart
class 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:dart
class 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