Dart语法汇总

Dart语法速查汇总


字符串操作

为了将表达式的值放在字符串中,请使用 ${expression}。若表达式为单个标识符,则可以省略 {}。

示例代码:

1
2
3
4
//字符串操作                       结果的值
'${3 + 2}' '5'
'${"word".toUpperCase()}' 'WORD'
'$myObject' myObject.toString()

避空运算符

Dart 提供了一系列方便的运算符用于处理可能会为空值的变量。其中一个是

  • ??= 赋值运算符,仅当该变量为空值时才为其赋值
  • ?? 如果该运算符左边的表达式返回的是空值,则会计算并返回右边的表达式

示例代码:

1
2
3
4
5
6
7
8
9
int a; // The initial value of any object is null.
a ??= 3;
print(a); // <-- Prints 3.

a ??= 5;
print(a); // <-- Still prints 3.

print(1 ?? 3); // <-- Prints 1.
print(null ?? 12); // <-- Prints 12.

条件属性访问

要保护可能会为空的属性的正常访问,需在点(.)之前加一个问号(?)

示例代码:

1
2
3
myObject?.someProperty
//上述代码等价于
(myObject != null) ? myObject.someProperty : null

集合字面量

  • Dart 内置了对 list、map 以及 set 的支持。你可以通过字面量直接创建它们

示例代码:

1
2
3
4
5
6
7
8
// list、map 以及 set
final aListOfStrings = ['one', 'two', 'three'];
final aSetOfStrings = {'one', 'two', 'three'};
final aMapOfStringsToInts = {
'one': 1,
'two': 2,
'three': 3,
};
  • Dart 的类型推断可以自动帮你分配这些变量的类型

示例代码:

1
2
3
4
// 推断类型是 List<String>、Set<String>和 Map<String, int>
final aListOfInts = <int>[];
final aSetOfInts = <int>{};
final aMapOfIntToDouble = <int, double>{};
  • 在使用子类型的内容初始化列表,但仍希望列表为List时,指定其类型很方便:

示例代码:

1
final aListOfBaseType = <BaseType>[SubType(), SubType()];

箭头语法

箭头语法是一种定义函数的方法,该函数将在其右侧执行表达式并返回其值

示例代码:

1
2
3
4
5
6
//正常
bool hasEmpty = aListOfStrings.any((s) {
return s.isEmpty;
});
//简写
bool hasEmpty = aListOfStrings.any((s) => s.isEmpty);

级连

对同一对象执行一系列操作,请使用级联(..)

示例代码:

1
2
3
4
5
6
7
8
9
10
//正常
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
//简写、使用级连能够让代码变得更加简洁,而且你也不再需要 button 变量了。
querySelector('#confirm')
..text = 'Confirm'
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));

Getters and setters

任何需要对属性进行更多控制而不是允许简单字段访问的时候,你都可以自定义 getter 和 setter

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyClass {
int _aProperty = 0;

int get aProperty => _aProperty;

set aProperty(int value) {
if (value >= 0) {
_aProperty = value;
}
}
}
//使用 getter 来定义计算属性
class MyClass {
List<int> _values = [];

void addValue(int value) {
_values.add(value);
}

// A computed property.
int get count {
return _values.length;
}
}

可选位置参数

Dart 有两种传参方法:位置参数和命名参数

  • 位置参数、示例代码:

    1
    2
    3
    4
    int sumUp(int a, int b, int c) {
    return a + b + c;
    }
    int total = sumUp(1, 2, 3);
  • 可选位置参数通过[]实现、示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int sumUpToFive(int a, [int b, int c, int d, int e]) {
    int sum = a;
    if (b != null) sum += b;
    if (c != null) sum += c;
    if (d != null) sum += d;
    if (e != null) sum += e;
    return sum;
    }
    int total = sumUptoFive(1, 2);
    int otherTotal = sumUpToFive(1, 2, 3, 4, 5);
    //给默认值
    int sumUpToFive(int a, [int b = 2, int c = 3, int d = 4, int e = 5]) {
    ...
    }

注意:可选位置参数永远放在方法参数列表的最后。除非你给它们提供一个默认值,否则默认为 null

可选命名参数

你可以使用大括号语法定义可选命名参数

示例代码:

1
2
3
4
5
6
7
8
9
10
void printName(String firstName, String lastName, {String suffix}) {
print('$firstName $lastName ${suffix ?? ''}');
}

printName('Avinash', 'Gupta');
printName('Poshmeister', 'Moneybuckets', suffix: 'IV');
//这些参数默认为 null,但你也可以为其提供默认值
void printName(String firstName, String lastName, {String suffix = ''}) {
print('$firstName $lastName ${suffix}');
}

注意:一个方法不能同时使用可选位置参数和可选命名参数。

异常

Dart 代码可以抛出和捕获异常。与 Java 相比,Dart 的所有异常都是 unchecked exception。方法不会声明它们可能抛出的异常,你也不需要捕获任何异常

  • 虽然 Dart 提供了 Exception 和 Error 类型,但是你可以抛出任何非空对象

示例代码:

1
2
throw Exception('Something bad happened.');
throw 'Waaaaaaah!';
  • 使用 try、on 以及 catch 关键字来处理异常:

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}

try 关键字作用与其他大多数语言一样。使用 on 关键字按类型过滤特定异常,而 catch 关键字则能够获取捕捉到的异常对象的引用。

  • 如果你无法完全处理该异常,请使用 rethrow 关键字再次抛出异常:
    示例代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    try {
    breedMoreLlamas();
    } catch (e) {
    print('I was just trying to breed llamas!.');
    rethrow;
    }
    //要执行一段无论是否抛出异常都会执行的代码,请使用 finally
    try {
    breedMoreLlamas();
    } catch (e) {
    … handle exception ...
    } finally {
    // Always clean up, even if an exception is thrown.
    cleanLlamaStalls();
    }

在构造方法中使用 this

Dart 提供了一个方便的快捷方式,用于为构造方法中的属性赋值:在声明构造方法时使用 this.propertyName。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MyColor {
int red;
int green;
int blue;

MyColor(this.red, this.green, this.blue);
}
final color = MyColor(80, 80, 128);

//此技巧同样也适用于命名参数。属性名为参数的名称:
class MyColor {
...

MyColor({this.red, this.green, this.blue});
}
final color = MyColor(red: 80, green: 80, blue: 80);

//对于可选参数,默认值为期望值:
MyColor([this.red = 0, this.green = 0, this.blue = 0]);
// or
MyColor({this.red = 0, this.green = 0, this.blue = 0})

Initializer lists

有时,当你在实现构造函数时,您需要在构造函数体执行之前进行一些初始化。例如,final 修饰的字段必须在构造函数体执行之前赋值。在初始化列表中执行此操作,该列表位于构造函数的签名与其函数体之间

示例代码:

1
2
3
4
5
6
7
8
9
10
11
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): ($x, $y)');
}
//初始化列表也是放置断言的便利位置,它仅会在开发期间运行:
NonNegativePoint(this.x, this.y)
: assert(x >= 0),
assert(y >= 0) {
print('I just made a NonNegativePoint: ($x, $y)');
}

命名构造方法

为了允许一个类具有多个构造方法,Dart 支持命名构造方法:

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
class Point {
num x, y;

Point(this.x, this.y);

Point.origin() {
x = 0;
y = 0;
}
}
//为了使用命名构造方法,请使用全名调用它:
final myPoint = Point.origin();

工厂构造方法

Dart 支持工厂构造方法。它能够返回其子类甚至 null 对象。要创建一个工厂构造方法,请使用 factory 关键字。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Square extends Shape {}

class Circle extends Shape {}

class Shape {
Shape();

factory Shape.fromTypeName(String typeName) {
if (typeName == 'square') return Square();
if (typeName == 'circle') return Circle();

print('I don\'t recognize $typeName');
return null;
}
}

重定向构造方法

有时一个构造方法仅仅用来重定向到该类的另一个构造方法。重定向方法没有主体,它在冒号(:)之后调用另一个构造方法
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Automobile {
String make;
String model;
int mpg;

// 这个类的主构造函数
Automobile(this.make, this.model, this.mpg);

// 委托给主构造函数
Automobile.hybrid(String make, String model) : this(make, model, 60);

// 委托给指定的构造函数
Automobile.fancyHybrid() : this.hybrid('Futurecar', 'Mark 2');
}

Const 构造方法

如果你的类生成的对象永远都不会更改,则可以让这些对象成为编译时常量。为此,请定义 const 构造方法并确保所有实例变量都是 final 的。

示例代码:

1
2
3
4
5
6
7
class ImmutablePoint {
const ImmutablePoint(this.x, this.y);
final int x;
final int y;
static const ImmutablePoint origin =
ImmutablePoint(0, 0);
}

参考来源