只适用于有编程基础的人
// for
main() {
List<String> colorList = ['red', 'yellow', 'blue', 'green'];
for (var i = 0; i < colorList.length; i++) { // 可以用var或int
print(colorList[i]);
}
}
// while
main() {
List<String> colorList = ['red', 'yellow', 'blue', 'green'];
var index = 0;
while (index < colorList.length) {
print(colorList[index++]);
}
}
// do-while
main() {
List<String> colorList = ['red', 'yellow', 'blue', 'green'];
var index = 0;
do {
print(colorList[index++]);
} while (index < colorList.length);
}
// break and continue
main() {
List<String> colorList = ['red', 'yellow', 'blue', 'green'];
for (var i = 0; i < colorList.length; i++) { // 可以用var或int
if(colorList[i] == 'yellow') {
continue;
}
if(colorList[i] == 'blue') {
break;
}
print(colorList[i]);
}
// if-else
void main() {
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for (var i = 0; i < numbers.length; i++) {
if (numbers[i].isEven) {
print('偶数: ${numbers[i]}');
} else if (numbers[i].isOdd) {
print('奇数: ${numbers[i]}');
} else {
print('非法数字');
}
}
}
// 三目运算符(? : )
void main() {
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for (var i = 0; i < numbers.length; i++) {
num targetNumber = numbers[i].isEven ? numbers[i] * 2 : numbers[i] + 4;
print(targetNumber);
}
}
// switch-case
Color getColor(String colorName) {
Color currentColor = Colors.blue;
switch (colorName) {
case "read":
currentColor = Colors.red;
break;
case "blue":
currentColor = Colors.blue;
break;
case "yellow":
currentColor = Colors.yellow;
break;
}
return currentColor;
}
断言只在检查模式下运行有效,如果在生产模式运行,则断言不会执行。
assert(text != null); // text为null,就会中断后续代码执行
assert(urlString.startsWith('https'));
名称 | 运算符 | 例子 |
---|---|---|
加 | + | var result = 1 + 1; |
减 | - | var result = 5 - 1; |
乘 | * | var result = 3 * 5; |
除 | / | var result = 3 / 5; // 0.6 |
整除 | ~/ | var result = 3 ~/ 5; // 0 |
取余 | % | var result = 5 % 3; // 2 |
名称 | 运算符 | 例子 |
---|---|---|
大于 | > | 2 > 1 |
小于 | < | 1 < 2 |
等于 | == | 1 == 1 |
不等于 | != | 3 != 4 |
大于等于 | >= | 5 >= 4 |
小于等于 | <= | 4 <= 5 |
名称 | 运算符 | 例子 |
---|---|---|
或 | || | 2 > 1 || 3 < 1 |
与 | && | 2 > 1 && 3 < 1 |
非 | ! | !(2 > 1) |
名称 | 运算符 |
---|---|
位与 | & |
位或 | | |
位非 | ~ |
异或 | ^ |
左移 | << |
右移 | >> |
// condition ? expr1 : expr2
var isOpened = (value == 1) ? true : false;
操作符 | 解释 |
---|---|
result = expr1 ?? expr2 | 若expr1为null, 返回expr2的值,否则返回expr1的值 |
expr1 ??= expr2 | 若expr1为null, 则把expr2的值赋值给expr1 |
result = expr1?.value | 若expr1为null, 就返回null,否则就返回expr1.value的值 |
main() {
var choice = question.choice ?? 'A';
// 等价于
var choice2;
if(question.choice == null) {
choice2 = 'A';
} else {
choice2 = question.choice;
}
}
main() {
var choice = question.choice ?? 'A';
// 等价于
var choice2;
if(question.choice == null) {
choice2 = 'A';
} else {
choice2 = question.choice;
}
}
main() {
var choice = question?.choice;
// 等价于
if(question == null){
return null;
} else {
return question.choice;
}
}
main() {
question?.commit();
// 等价于
if(question == null){
return; // 不执行 commit()
} else {
question.commit(); // 执行commit方法
}
}
级联操作符是 ..
, 可以让你对一个对象中字段进行链式调用操作,类似Kotlin中的apply或run标准库函数的使用。
question
..id = '10001'
..stem = '第一题: xxxxxx'
..choices = <String> ['A','B','C','D']
..hint = '听音频做题';
Kotlin中的run函数实现对比
question.run {
id = '10001'
stem = '第一题: xxxxxx'
choices = <String> ['A','B','C','D']
hint = '听音频做题'
}
在dart支持运算符自定义重载,使用 operator
关键字定义重载函数
class Vip {
final int level;
final int score;
const Vip(this.level, this.score);
bool operator > (Vip other) =>
level > other.level || (level == other.level && score > other.score);
bool operator < (Vip other) =>
level < other.level || (level == other.level && score < other.score);
// 注意: 这段代码可能在高版本的Dart中会报错,在低版本是OK的
bool operator == (Vip other) =>
level == other.level && score == other.level;
// 上述代码在高版本 Dart 中,Object 中已经重载了 ==,
// 所以需要加上 covariant 关键字重写这个重载函数。
@override
bool operator == (covariant Vip other) =>
(level == other.level && score == other.score);
// 伴随着你还需要重写 hashCode,至于什么原因大家应该都知道
@override
int get hashCode => super.hashCode;
}
main() {
var userVip1 = Vip(4, 3500);
var userVip2 = Vip(4, 1200);
if(userVip1 > userVip2) {
print('userVip1 is super vip');
} else if(userVip1 < userVip2) {
print('userVip2 is super vip');
}
}
Dart 中的异常捕获方法和 Java,Kotlin 类似,使用的也是 try-catch-finally
,对特定异常的捕获使用 on
关键字,Dart 中的常见异常有:
NoSuchMethodError
:当在一个对象上调用一个该对象没有实现的函数会抛出该错误。ArgumentError
:调用函数的参数不合法会抛出这个错误。main() {
int num = 18;
int result = 0;
try {
result = num ~/ 0;
} catch (e) { // 捕获到IntegerDivisionByZeroException
print(e.toString());
} finally {
print('$result');
}
}
//使用on关键字捕获特定的异常
main() {
int num = 18;
int result = 0;
try {
result = num ~/ 0;
} on IntegerDivisionByZeroException catch (e) { // 捕获特定异常
print(e.toString());
} finally {
print('$result');
}
}
在 Dart 中函数的地位一点都不亚于对象,支持闭包和高阶函数,而且 Dart 中的函数也会比 Java 要灵活的多,而且 Kotlin 中的一些函数特性,它也支持甚至比 Kotlin 支持的更全面。比如支持默认值参数、可选参数、命名参数等。
main() {
print('sum is ${sum(2, 5)}');
}
num sum(num a, num b) {
return a + b;
}
// num a, num b, num c, num d 最普通的传参:
// 调用时,参数个数和参数顺序必须固定。
add1(num a, num b, num c, num d) {
print(a + b + c + d);
}
// [num a, num b, num c, num d] 传参:
// 调用时,参数个数不固定,但是参数顺序需要一一对应, 不支持命名参数。
add2([num a, num b, num c, num d]) {
print(a + b + c + d);
}
// {num a, num b, num c, num d} 传参:
// 调用时,参数个数不固定,参数顺序也可以不固定,支持命名参数,也叫可选参数,
// 是 Dart 中的一大特性,这就是为啥 Flutter 代码那么多可选属性,大量使用可选参数。
add3({num a, num b, num c, num d}) {
print(a + b + c + d);
}
// num a, num b, {num c, num d} 传参:
// 调用时,a, b 参数个数固定顺序固定,c, d 参数个数和顺序也可以不固定。
add4(num a, num b, {num c, num d}) {
print(a + b + c + d);
}
main() {
// 最普通的传参: 调用时,参数个数和参数顺序必须固定。
add1(100, 100, 100, 100);
// 调用时,参数个数不固定,但是参数顺序需要一一对应, 不支持命名参数(也就意味着顺序不变)。
add2(100, 100);
// 调用时,参数个数不固定,参数顺序也可以不固定,支持命名参数(也就意味着顺序可变)。
add3(b: 200, a: 200, c: 100, d: 100);
// 调用时,a, b 参数个数固定顺序笃定,c, d 参数个数和顺序也可以不固定。
add4(100, 100, d: 100, c: 100);
}
Dart 中函数的默认值参数和可选参数和 Kotlin 中默认值参数和命名参数一致,只是写法上不同而已。
// d 就是默认值参数,给的默认值是 100
add3({num a, num b, num c, num d = 100}) {
print(a + b + c + d);
}
main() {
add3(b: 200, a: 100, c: 800);
}
在 Dart 中函数也是一种类型 Function
,可以作为函数参数传递,也可以作为返回值。类似 Kotlin 中的 FunctionN
系列函数。
main() {
Function square = (a) {
return a * a;
};
Function square2 = (a) {
return a * a * a;
};
add(3, 4, square, square2)
}
num add(num a, num b, [Function op, Function op2]) {
//函数作为参数传递
return op(a) + op2(b);
}
在 Dart 中如果在函数体内只有一个表达式,那么就可以使用箭头函数来简化代码,这点也和Kotlin类似,只不过在Kotlin中人家叫lambda表达式,只是写法上不一样而已。
add4(num a, num b, {num c, num d}) {
print(a + b + c + d);
}
add5(num a, num b, {num c, num d}) => print(a + b + c + d);
在 Dart 中一切皆是对象,所以面向对象在Dart中依然举足轻重,下面就先通过一个简单的例子认识下 Dart 的面向对象,后续会继续深入。
abstract class Person {
String name;
int age;
double height;
// 注意,这里写法可能大家没见过, 这点和 Java 是不一样,这里实际上是一个 Dart 的语法糖。
// 但是这里不如 Kotlin,Kotlin 是直接把 this.name 传值的过程都省了。
Person(this.name, this.age, this.height);
// 与上述的等价代码,当然这也是Java中必须要写的代码
Person(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
// 然而 Kotlin 很彻底只需要声明属性就行,下面是 Kotlin 实现代码
abstract class Person(val name: String, val age: Int, val height: Double)
}
// 和 Java 一样同时使用 extends 关键字表示继承
class Student extends Person {
// 在 Dart 里:类名(变量,变量,...) 是构造函数的写法,
// `:super()` 表示该构造调用父类,这里构造时传入三个参数。
Student(String name, int age, double height, double grade): super(name, age, height);
}
abstract class Person {
// 相当于kotlin中的var 修饰的变量有setter、getter访问器,在dart中没有访问权限,
// 默认 `_` 下划线开头变量表示私有权限,外部文件无法访问。
String _name;
// 相当于kotlin中的val 修饰的变量只有getter访问器
final int _age;
//这是上述简写形式
Person(this._name, this._age);
// 使用 set 关键字 计算属性 自定义 `setter` 访问器
set name(String name) => _name = name;
// 使用 get 关键字 计算属性 自定义 `getter` 访问器
bool get isStudent => _age > 18;
}
只是了解 Dart 语法时顺手重新排了个版,后续文章可以看原作者的专栏:Flutter 深入浅出系列