Dart 笔记
创建于:
Miscellaneous
- Everything in a variable is an object (except for
nullin 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 &
latevariables are lazily initialized finalvsconstfinal: set only onceconst: compile-time constants (not immutable)
Types
Number
intanddoublenum, 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:
voiddartvoid 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 == yinvokes==method onxwith arguemnty(when both non-null).
Useidentical(a, b)to check whetheraandbrefer 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 : expr2expr1 ?? 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
caseclause can either be empty or end with a keyword (break,continue,throw,return default- Use
continueand label to fallbackdartswitch() { case 1: executeSomething(); continue myLabel; myLabel: case 2: executeSomething(); break; default: break; } - A
caseclause has its local variables
Exceptions
Throw
- All non-null object can be throwed
- Usually throw
ExceptionorError
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
constbefore constructors - Constant constructors cannot have body
- Example:dart
class ImmutablePoint { final double x, y; const ImmutablePoint(this.x, this.y); }
- Factory constructors
Usefactorykeyword for constructors that don't always create a new instance.
- Generative constructor
TODO
Generics, TODO
TODO
