当前位置: 首页>后端>正文

Dart速来系列4,那些关于操作符(expr),流程控制(flow),错误(err)的事

一、操作符

emm,老生常谈了。

用于赋值、运算、函数调用等各种场景。

gogogogo。

  1. 什么是表达式?

表达式是一种计算值的代码片段。它可以由字面量(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; // 条件表达式

在上述示例中,我们使用了不同类型的表达式,包括字面量表达式、算术表达式、逻辑表达式、字符串拼接表达式和条件表达式。

  1. 表达式的分类

在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');
}

在上述示例中,我们展示了函数调用表达式的使用,包括无参数的函数调用和带参数的函数调用。

  1. 表达式的应用场景

表达式在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中都是相似的,都强调对异常的识别、捕获和适当的处理。


https://www.xamrdz.com/backend/3nk1933821.html

相关文章: