Flutter 语法

Null-aware operators

1
2
3
4
5
6
7
8
9
10
String foo = 'a string';
String bar; // Unassigned objects are null by default.

// Substitute an operator that makes 'a string' be assigned to baz.
String baz = foo ?? bar;

void updateSomeVars() {
// Substitute an operator that makes 'a string' be assigned to bar.
bar ??= 'a string';
}

Conditional property access

myObject?.someProperty equals to (myObject != null) ? myObject.someProperty : null.

1
2
3
4
5
6
// This method should return the uppercase version of `str`
// or null if `str` is null.
String upperCaseIt(String str) {
// Try conditionally accessing the `toUpperCase` method here.
return str?.toUpperCase();
}

Cascades

myObject.someMethod() will get the return value of the someMethod(), myObject..someMethod() will get the reference of the myObject.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class BigObject {
int anInt = 0;
String aString = '';
List<double> aList = [];
bool _done = false;

void allDone() {
_done = true;
}
}

BigObject fillBigObject(BigObject obj) {
// Create a single statement that will update and return obj:
return obj
..anInt = 1
..aString = "String!"
..aList = [3.0]
..allDone();
}

Optional named parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyDataObject {
final int anInt;
final String aString;
final double aDouble;

MyDataObject({
this.anInt = 1,
this.aString = 'Old!',
this.aDouble = 2.0,
});

// Add your copyWith method here:
MyDataObject copyWith({int newInt, String newString, double newDouble}) {
return MyDataObject(anInt: newInt ?? this.anInt,
aString: newString ?? this.aString,
aDouble: newDouble ?? this.aDouble
);
}
}

Initializer lists

1
2
3
4
5
6
7
8
9
10
class FirstTwoLetters {
final String letterOne;
final String letterTwo;

// Create a constructor with an initializer list here:
FirstTwoLetters(String word)
: assert(word.length >= 2),
letterOne = word[0],
letterTwo = word[1] {}
}

Named constructors

1
2
3
4
5
6
7
8
9
10
11
12
13
class Color {
int red;
int green;
int blue;

Color(this.red, this.green, this.blue);

Color.black() {
red = 0;
green = 0;
blue = 0;
}
}

Factory constructors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class IntegerHolder {
IntegerHolder();

// Create your factory constructor called "fromList" here.
factory IntegerHolder.fromList(List<int> list) {
if (list.length == 1) return IntegerSingle(list[0]);
if (list.length == 2) return IntegerDouble(list[0], list[1]);
if (list.length == 3) return IntegerTriple(list[0], list[1], list[2]);
return null;
}
}

class IntegerSingle extends IntegerHolder {
final int a;
IntegerSingle(this.a);
}

class IntegerDouble extends IntegerHolder {
final int a;
final int b;
IntegerDouble(this.a, this.b);
}

class IntegerTriple extends IntegerHolder {
final int a;
final int b;
final int c;
IntegerTriple(this.a, this.b, this.c);
}

Redirecting constructors

1
2
3
4
5
6
7
8
9
10
11
12
class Color {
int red;
int green;
int blue;

Color(this.red, this.green, this.blue);

// Create a named constructor called "black" here and redirect it
// to call the existing constructor
Color.assign(int red, int green, int blue): this(red, green, blue);
Color.black(): this.assign(0, 0, 0);
}

Const constructors

1
2
3
4
5
6
7
class Recipe {
final List<String> ingredients;
final int calories;
final double milligramsOfSodium;

const Recipe(this.ingredients, this.calories, this.milligramsOfSodium);
}