一、操作符
emm,老生常谈了。
用于赋值、运算、函数调用等各种场景。
gogogogo。
- 什么是表达式?
表达式是一种计算值的代码片段。它可以由字面量(literal)、变量、函数调用、运算符和其他表达式组成。表达式由编译器或解释器计算并产生一个值。
在Dart中,表达式可以是简单的值(如整数、浮点数、字符串等),也可以是复杂的表达式(如算术运算、逻辑运算、函数调用等)。表达式可以在赋值语句、条件语句、循环语句以及函数中使用。
下面是一些示例,展示了不同类型的Dart表达式:
int a = 10; // 字面量表达式
double b = 3.14;
String greeting = 'Hello';
int sum = a + 5; // 算术表达式
double result = b * 2;
bool isGreaterThan = a > 5; // 逻辑表达式
String message = greeting + '!'; // 字符串拼接表达式
bool isValid = message.isNotEmpty;
int maxNumber = (a > b) a : b; // 条件表达式
在上述示例中,我们使用了不同类型的表达式,包括字面量表达式、算术表达式、逻辑表达式、字符串拼接表达式和条件表达式。
- 表达式的分类
在Dart中,表达式可以分为以下几个主要的分类:
2.1. 基础表达式
基础表达式包括字面量表达式、标识符表达式和成员访问表达式。
- 字面量表达式:直接使用常量值,如整数、浮点数、布尔值和字符串等。
- 标识符表达式:表示变量、函数、类或命名构造函数等标识符的引用。
- 成员访问表达式:通过点号(.)或问号点号(?.)访问对象的属性或方法。
int number = 10; // 字面量表达式
String name = 'Alice';
int result = number + 5; // 算术表达式
String greeting = name + '!';
String firstLetter = name[0]; // 字符串索引表达式
在上述示例中,我们展示了基础表达式的使用,包括字面量表达式、标识符表达式、成员访问表达式和字符串索引表达式。
2.2. 运算符表达式
运算符表达式使用运算符对值或表达式进行运算,包括算术运算、逻辑运算、比较运算和位运算等。
int a = 10;
int b = 5;
int sum = a + b; // 加法运算
int difference = a - b; // 减法运算
int product = a * b; // 乘法运算
double quotient = a / b; // 除法运算
int remainder = a % b; // 取余运算
bool isGreaterThan = a > b; // 大于运算
bool isEqual = a == b; // 等于运算
bool logicalAnd = (a > 0) && (b < 10); // 逻辑与运算
bool logicalOr = (a > 0) || (b < 10); // 逻辑或运算
bool logicalNot = !(a > 0); // 逻辑非运算
int bitwiseAnd = a & b; // 位与运算
int bitwiseOr = a | b; // 位或运算
int bitwiseXor = a ^ b; // 位异或运算
int bitwiseNot = ~a; // 位非运算
int leftShift = a << b; // 左移运算
int rightShift = a >> b; // 右移运算
在上述示例中,我们展示了不同类型的运算符表达式,包括算术运算、逻辑运算、比较运算和位运算等。
2.3. 函数调用表达式
函数调用表达式使用函数名称和参数列表调用函数,并返回函数的返回值。
void sayHello() {
print('Hello!');
}
int calculateSum(int a, int b) {
return a + b;
}
void main() {
sayHello(); // 无参数的函数调用
int sum = calculateSum(3, 5); // 带参数的函数调用
print('Sum: $sum');
}
在上述示例中,我们展示了函数调用表达式的使用,包括无参数的函数调用和带参数的函数调用。
- 表达式的应用场景
表达式在Dart中广泛应用于各种编程场景,包括:
- 赋值语句:使用表达式计算并将值赋给变量。
- 条件语句:根据表达式的值执行不同的逻辑分支。
- 循环语句:使用表达式控制循环的条件。
- 函数定义和调用:使用表达式定义函数体内的逻辑,并传递参数调用其他函数。
下面是一些示例,展示了表达式在不同场景中的应用:
void main() {
// 赋值语句
int a = 10;
int b = a + 5;
// 条件语句
if (b > 10) {
print('B is greater than 10');
} else {
print('B is less than or equal to 10');
}
// 循环语句
for (int i = 0; i < 5; i++) {
print('Count: $i');
}
// 函数定义和调用
int calculateSum(int a, int b) {
return a + b;
}
int sum = calculateSum(3, 5);
print('Sum: $sum');
}
4、.dart中的各种遍历
但是呢,既然说到了for,那么就可以顺便说说Dart中的几种遍历。
- for
- forEach
- 迭代器
1. 使用for循环遍历
for循环是一种常见的遍历方式,可以用于遍历列表、数组和字符串等有序集合。
1.1. 遍历列表和数组
使用for循环可以遍历列表(List)和数组(Array),通过索引逐个访问元素。
List<int> numbers = [1, 2, 3, 4, 5];
for (int i = 0; i < numbers.length; i++) {
print(numbers[i]);
}
在上述示例中,我们使用for循环遍历了一个整数列表,并通过索引访问并打印了每个元素。
1.2. 遍历字符串
使用for循环也可以遍历字符串,通过索引逐个访问字符串的字符。
String message = 'Hello, Dart!';
for (int i = 0; i < message.length; i++) {
print(message[i]);
}
在上述示例中,我们使用for循环遍历了一个字符串,并通过索引访问并打印了每个字符。
2. 使用forEach方法遍历
Dart的集合类型提供了forEach方法,可以更简洁地进行遍历操作。
2.1. 遍历列表和数组
使用forEach方法可以遍历列表(List)和数组(Array),通过匿名函数逐个访问元素。
List<int> numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) {
print(number);
});
在上述示例中,我们使用forEach方法遍历了一个整数列表,并通过匿名函数访问并打印了每个元素。
2.2. forEach遍历映射 Map
对于映射(Map),我们可以使用forEach方法遍历键值对。
Map<String, int> scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92};
scores.forEach((key, value) {
print('$key: $value');
});
在上述示例中,我们使用forEach方法遍历了一个键值对映射,并通过匿名函数访问并打印了每个键值对。
3. 使用迭代器遍历
除了for循环和forEach方法,我们还可以使用迭代器(Iterator)来遍历集合中的元素。
3.1. 遍历列表和数组
使用迭代器可以遍历列表(List)和数组(Array),通过调用迭代器的moveNext和current属性逐个访问元素。
List<int> numbers = [1, 2, 3, 4, 5];
Iterator<int> iterator = numbers.iterator;
while (iterator.moveNext()) {
print(iterator.current);
}
在上述示例中,我们使用迭代器遍历了一个整数列表,并通过迭代器的current属性访问并打印了每个元素。
3.2. 遍历映射
对于映射(Map),我们可以使用迭代器遍历键值对。
Map<String, int> scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92};
Iterator<MapEntry<String, int>> iterator = scores.entries.iterator;
while (iterator.moveNext()) {
MapEntry<String, int> entry = iterator.current;
print('${entry.key}: ${entry.value}');
}
在上述示例中,我们使用迭代器遍历了一个键值对映射,并通过迭代器的current属性访问并打印了每个键值对。
4. 使用递归遍历
递归是一种自我调用的方法,可以用于遍历树状结构或者嵌套的集合。
void printNestedList(List<dynamic> list) {
for (dynamic element in list) {
if (element is List<dynamic>) {
printNestedList(element); // 递归调用自身遍历嵌套的列表
} else {
print(element);
}
}
}
List<dynamic> nestedList = [1, [2, [3, 4], 5], 6];
printNestedList(nestedList);
在上述示例中,我们使用递归方法printNestedList遍历了一个嵌套列表,并通过递归调用自身实现了对嵌套列表的遍历。
二、流程控制
在Dart编程中,流程控制用于控制程序的执行流程
,包括条件判断
、循环
和分支
等。
1. 条件判断语句
条件判断语句用于根据不同的条件执行不同的代码块。Dart提供了if语句、else语句、else if语句和switch语句等用于条件判断的结构。
1.1. if语句
if语句用于执行一个代码块,当给定的条件为真时。
int age = 18;
if (age >= 18) {
print('You are an adult.');
}
在上述示例中,如果年龄大于等于18,将会打印出"You are an adult."。
1.2. else语句
else语句用于在条件为假时执行另一个代码块。
int age = 16;
if (age >= 18) {
print('You are an adult.');
} else {
print('You are a minor.');
}
在上述示例中,如果年龄小于18,将会打印出"You are a minor."。
1.3. else if语句
else if语句用于在多个条件之间进行判断,可以有多个else if语句。
int age = 25;
if (age < 18) {
print('You are a minor.');
} else if (age >= 18 && age < 60) {
print('You are an adult.');
} else {
print('You are a senior citizen.');
}
在上述示例中,根据年龄的不同,将打印出不同的消息。
1.4. switch语句
switch语句用于根据不同的条件执行不同的代码块。
String day = 'Monday';
switch (day) {
case 'Monday':
print('Today is Monday.');
break;
case 'Tuesday':
print('Today is Tuesday.');
break;
default:
print('Today is another day.');
break;
}
在上述示例中,根据不同的星期几,将打印出不同的消息。
2. 循环语句
循环语句用于重复执行一段代码,Dart提供了for循环、while循环和do-while循环等多种循环结构。
2.1. for循环
for循环用于在指定条件下重复执行一个代码块。
for (int i = 0; i < 5; i++) {
print(i);
}
在上述示例中,将打印出从0到4的数字。
2.2. while循环
while循环用于在给定条件为真时重复执行一个代码块。
int count = 0;
while (count < 5) {
print(count);
count++;
}
在上述示例中,将打印出从0到4的数字。
2.3. do-while循环
do-while循环用于先执行一次代码块,然后在给定条件为真时重复执行。
int count = 0;
do {
print(count);
count++;
} while (count < 5);
在上述示例中,将打印出从0到4的数字。
3. 分支语句
分支语句用于根据不同的条件执行不同的代码块。Dart提供了break语句和continue语句来控制分支的执行流程。
3.1. break语句
break语句用于在循环或switch语句中提前结束代码块的执行。
for (int i = 0; i < 5; i++) {
if (i == 3) {
break;
}
print(i);
}
在上述示例中,当i等于3时,循环将会被提前结束。
3.2. continue语句
continue语句用于跳过循环中的某一次迭代。
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue;
}
print(i);
}
在上述示例中,当i等于3时,循环将会跳过该次迭代。
三、异常
Emm,是的,你熟悉的异常。
呸呸呸!!!
1. 异常的概念
异常是指在程序执行过程中发生的意外情况或错误,可能导致程序无法正常继续执行。在Dart中,异常是通过抛出(Throw)和捕获(Catch)机制来处理的。
1.1. 异常的抛出
在Dart中,可以使用throw
关键字抛出异常。抛出异常后,程序将立即停止当前执行路径,并寻找匹配的异常处理代码进行处理。
void divideNumbers(int a, int b) {
if (b == 0) {
throw Exception('Cannot divide by zero!'); // 抛出异常
}
print(a ~/ b);
}
void main() {
try {
divideNumbers(10, 0); // 调用函数可能抛出异常
} catch (e) {
print('发生错误: $e'); // 捕获并处理异常
}
}
在上述示例中,我们定义了一个divideNumbers
函数,用于计算两个数的商。如果除数为零,将抛出一个自定义的异常。在main
函数中,我们使用try-catch
语句捕获并处理异常。
1.2. 异常的捕获
在Dart中,可以使用try-catch
语句捕获并处理异常。try
代码块中包含可能抛出异常的代码,而catch
代码块用于处理捕获到的异常。
void divideNumbers(int a, int b) {
if (b == 0) {
throw Exception('Cannot divide by zero!'); // 抛出异常
}
print(a ~/ b);
}
void main() {
try {
divideNumbers(10, 0); // 调用函数可能抛出异常
} catch (e) {
print('发生错误: $e'); // 捕获并处理异常
}
}
在上述示例中,我们在try
代码块中调用divideNumbers
函数,由于除数为零,将抛出异常。在catch
代码块中,我们捕获并处理了异常,打印出错误消息。
2. 异常处理的语法和技巧
除了基本的try-catch
语句外,Dart还提供了一些语法和技巧,帮助开发者更好地处理异常。
2.1. 多个catch语句
可以使用多个catch
语句来捕获不同类型的异常,并进行相应的处理。
void divideNumbers(int a, int b) {
if (b == 0) {
throw Exception('Cannot divide by zero!'); // 抛出异常
}
print(a ~/ b);
}
void main() {
try {
divideNumbers(10, 0); // 调用函数可能抛出异常
} on IntegerDivisionByZeroException {
print('除数不能为零'); // 捕获特定类型的异常
} catch (e) {
print('发生错误: $e'); // 捕获其他类型的异常
}
}
在上述示例中,我们添加了一个额外的catch
语句,用于捕获特定类型的异常并进行处理。
2.2. finally语句
finally
语句用于定义一段无论是否发生异常都会执行的代码块。无论是否发生异常,finally
中的代码都会在异常处理完成后执行。
void divideNumbers(int a, int b) {
try {
if (b == 0) {
throw Exception('Cannot divide by zero!'); // 抛出异常
}
print(a ~/ b);
} finally {
print('除法运算完成'); // 无论是否发生异常,都会执行
}
}
void main() {
divideNumbers(10, 2);
}
在上述示例中,无论是否发生异常,finally
中的代码都会被执行,用于进行清理工作或释放资源。
3. 错误处理的最佳实践
在处理错误时,以下是一些Dart错误处理的最佳实践:
- 使用适当的异常类型:Dart提供了多种异常类型,包括通用的
Exception
、类型错误的TypeError
、范围错误的RangeError
等。根据具体的错误类型选择合适的异常类型。 - 捕获并处理特定的异常:在
catch
语句中尽量精确地捕获特定类型的异常,以便能够针对性地处理不同类型的错误。 - 记录错误信息:在异常处理中,记录错误信息可以帮助调试和排查问题。可以使用日志库(如
logging
)或打印错误消息和堆栈跟踪信息来记录错误。 - 调用方处理异常:在库或函数中抛出异常时,应该让调用方适当地处理异常。可以通过抛出自定义异常、返回特定的错误码或提供默认值等方式来处理异常。
4. 与Java和Kotlin的对比
在错误处理方面,Dart与Java和Kotlin有一些相似之处,但也存在一些差异。
- 异常类型:Dart中的异常是
Exception
类的子类,而Java和Kotlin中的异常是层次化的类结构,包括受检查异常(checked exception)和非受检查异常(unchecked exception)。 - 异常处理语法:Dart使用
try-catch
语句来捕获和处理异常,与Java的语法类似。Kotlin引入了更简洁的try-catch
表达式,可以在表达式中处理异常,同时也支持常规的try-catch-finally
语句。 - finally语句:Dart和Java都提供了
finally
语句来定义无论是否发生异常都会执行的代码块。而在Kotlin中,finally
语句被替换为finally
表达式,它具有更灵活的用法。
虽然在细节上存在差异,但错误处理的基本概念和原则在Dart、Java和Kotlin中都是相似的,都强调对异常的识别、捕获和适当的处理。