学习 Dart 反常处理:预见过错,优雅应对

在程序运行过程中,反常是不可防止的。网络反常、文件读取过错、日期格式问题等,都或许引发程序中止。不仅需要处理反常以保证程序不中止,还能更轻松地排查问题。

1. 反常的触发

以下测验中,task1 办法将字符串转为数字,若传非数字,将产生转化反常,中止 task2 的履行。

void main(){
  task1('a');
  task2();
}
int task1(String num){
  return int.parse(num);
}
void task2(){
  print("Task2");
}

2. 反常的捕捉

运用 try...catch... 捕捉反常。catch 中的参数:

  • e 表明反常目标,如 FormatException
  • s_StackTrace,记录反常的栈信息
void main(){
  try{
    task1('a');
  } catch(e, s){
    print("${e.runtimeType}: ${e.toString()}"); 
    print("${s.runtimeType}: ${s.toString()}"); 
  }
  task2(); // Task2
}

反常被捕获,程序不中止,task2 仍履行。

3. 自界说反常与抛出

Exception 是反常的顶层抽象类,可结构运行时类型为 _Exception 的反常目标,传入信息。

void main() {
  try {
    getMean("about");
  } catch (e, s) {
    print("${e.runtimeType}: ${e.toString()}");
    print("${s.runtimeType}: ${s.toString()}");
  }
}
String getMean(String arg) {
  Map<String, String> dict = {"card": "卡片", "but": "可是"};
  String? result = dict[arg];
  if (result == null) {
    throw Exception("empty $arg mean in dict");
  }
  return result;
}

4. 分类反常处理

可拓展 Exception 类以自界说反常类型。运用 on/catch 捕获不同反常类型。

void main() {
  try {
    getMean("about");
  } on NoElementInDictException catch (e, s) {
    // 特定反常处理
  } catch (e, s) {
    // 其他反常处理
  }
}

5. finally 要害字

finally 用于 catch 之后,无论反常与否,都履行。防止多次重复写 finally 代码块。

void foo2(){
  try {
    getMean("about");
  } catch (e, s) {
    print("${e.runtimeType}: ${e.toString()}");
    print("${s.runtimeType}: ${s.toString()}");
  } finally{
    print("finally block called");
  }

反常处理是 Dart 编程的要害,保证程序鲁棒性和可维护性。遵从最佳实践,优雅应对反常,将让你的代码更具强健性。

学习 Dart | 类与成员可见性

本文将深化探讨 Dart 中的类及其成员可见性,构建坚实的面向目标基础。

类的界说与实例化

Dart 运用 class 要害字界说类,经过 {} 界说类的效果域,包含成员变量和成员办法。

class $className$ {
  // 类体
}

1. 类的简略界说与实例化

Vec2 类为例,界说包含两个 double 变量的类,用结构办法初始化。

class Vec2 {
  double x;
  double y;
  Vec2(this.x, this.y);
}

经过结构办法实例化 Vec2 类,拜访和修正成员变量:

void main() {
  Vec2 p0 = Vec2(4, 3);
  print("Vec2(${p0.x},${p0.y})"); // Vec2(4.0,3.0)
  p0.x = 15;
  print("Vec2(${p0.x},${p0.y})"); // Vec2(15.0,3.0)
}

2. 成员办法

除成员变量外,类还可以界说成员办法。例如,为 Vec2 供给 getInfo 办法获取打印信息:

class Vec2 {
  double x;
  double y;
  Vec2(this.x, this.y);
  String getInfo() => "Vec2($x,$y)";
}

调用成员办法简化代码:

void main() {
  Vec2 p0 = Vec2(4, 3);
  print(p0.getInfo()); // Vec2(4.0,3.0)
  p0.x = 15;
  print(p0.getInfo()); // Vec2(15.0,3.0)
}

3. get 与 set 要害字

getset 修饰成员办法,供给属性式拜访。如 length 计算向量长度:

class Vec2 {
  // ...
  double get length => math.sqrt(x * x + y * y);
}

运用属性式拜访 length

Vec2 p0 = Vec2(4, 3);
print(p0.length); // 5.0

4. 类的结构办法

结构办法是连接类与目标的桥梁,特点包含无返回值、可无办法体、可对成员进行赋值。

class Vec2 {
  double x;
  double y;
  Vec2(this.x, this.y);
}

运用结构办法实例化目标,支持命名参数:

Vec2 p0 = Vec2(4, 3);
Vec2 p1 = Vec2(argX: 4, argY: 3);

5. 命名结构

经过命名结构创立多种实例化办法,如 Vec2.polar 结构办法:

class Vec2 {
  Vec2.polar(double length, double rad)
      : x = length * math.cos(rad),
        y = length * math.sin(rad);
}

运用命名结构创立目标:

Vec2 p1 = Vec2.polar(10, math.pi / 4);

成员和类的可见性

运用 _ 前缀约束成员可见性,私有成员仅限同一文件拜访。

class Vec2 {
  double x;
  double y;
  String? _name;
  Vec2(this.x, this.y);
  String getInfo() => "${name}Vec2($x,$y)";
  double get length => math.sqrt(x * x + y * y);
  String get name => _name ?? "";
  set name(String? value) {
    _name = value == null ? "" : value + ": ";
  }
}

约束私有成员可见性,保证封装与安全性。

静态成员与静态办法

静态成员由类直接拜访,运用 static 要害字界说静态成员和静态办法:

class Person {
  String name;
  static String nation = "";
  Person(this.name);
  static void printNation() {
    print("Current nation is: $nation");
  }
  void say() {
    print("I am $name, from $nation");
  }
}

运用静态成员和静态办法,无需实例化目标:

Person.nation = "Tang Dynasty";
print(Person.nation); // Tang Dynasty
Person.printNation(); // Current nation is: Tang Dynasty

经过类直接拜访静态成员,实现大局同享数据和办法。

结语

本文深化介绍了 Dart 类的界说与实例化、结构办法、成员办法、可见性和静态成员等基础概念。掌握这些核心概念将帮助你更好地构建强健的面向目标程序,为进一步探索类与类间的关系打下坚实基础。