企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 异常(Exceptions) 1. ***throw*** * 抛出固定类型的异常 ~~~ throw new FormatException('Expected at least 1 section'); ~~~ * 抛出任意类型的异常 ~~~ throw 'Out of llamas!'; ~~~ * 因为抛出异常属于表达式,可以将throw语句放在=>语句中,或者其它可以出现表达式的地方 ~~~ distanceTo(Point other) => throw new UnimplementedError(); ~~~ 2. ***catch*** * 将可能出现异常的代码放置到try语句中,可以通过 on语句来指定需要捕获的异常类型,使用catch来处理异常。 ~~~ try { breedMoreLlamas(); } on OutOfLlamasException { // A specific exception buyMoreLlamas(); } on Exception catch (e) { // Anything else that is an exception print('Unknown exception: $e'); } catch (e, s) { print('Exception details:\n $e'); print('Stack trace:\n $s'); } ~~~ 3. ***rethrow*** * rethrow语句用来处理一个异常,同时希望这个异常能够被其它调用的部分使用。 ~~~ final foo = ''; void misbehave() { try { foo = "1"; } catch (e) { print('2'); rethrow;// 如果不重新抛出异常,main函数中的catch语句执行不到 } } void main() { try { misbehave(); } catch (e) { print('3'); } } ~~~ 4. ***finally*** * Dart的finally用来执行那些无论异常是否发生都执行的操作。 ~~~ final foo = ''; void misbehave() { try { foo = "1"; } catch (e) { print('2'); } } void main() { try { misbehave(); } catch (e) { print('3'); } finally { print('4'); // 即使没有rethrow最终都会执行到 } } ~~~ ### 函数 Function * 以下是一个实现函数的例子: ~~~ bool isNoble(int atomicNumber) { return _nobleGases[atomicNumber] != null; } ~~~ 1. ***main()函数*** * 每个应用程序都必须有一个顶层main()函数,它可以作为应用程序的入口点。该main()函数返回void并具有List参数的可选参数。 ~~~ void main() { querySelector('#sample_text_id') ..text = 'Click me!' ..onClick.listen(reverseText); } ~~~ * 级联符号..允许您在同一个对象上进行一系列操作。除了函数调用之外,还可以访问同一对象上的字段。这通常会为您节省创建临时变量的步骤,并允许您编写更流畅的代码。 ~~~ querySelector('#confirm') // Get an object. ..text = 'Confirm' // Use its members. ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!')); ~~~ * 上述例子相对于: ~~~ var button = querySelector('#confirm'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!')); ~~~ * 级联符号也可以嵌套使用。 例如: ~~~ final addressBook = (AddressBookBuilder() ..name = 'jenny' ..email = 'jenny@example.com' ..phone = (PhoneNumberBuilder() ..number = '415-555-0100' ..label = 'home') .build()) .build(); ~~~ * 当返回值是void时不能构建级联。 例如,以下代码失败: ~~~ var sb = StringBuffer(); sb.write('foo') // 返回void ..write('bar'); // 这里会报错 ~~~ * ***注意: 严格地说,级联的..符号不是操作符。它只是Dart语法的一部分。*** 2. ***可选参数*** * 可选的命名参数, 定义函数时,使用{param1, param2, …},用于指定命名参数。例如: ~~~ //设置[bold]和[hidden]标志 void enableFlags({bool bold, bool hidden}) { // ... } enableFlags(bold: true, hidden: false); ~~~ * 可选的位置参数,用\[\]它们标记为可选的位置参数: ~~~ String say(String from, String msg, [String device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } return result; } ~~~ * 下面是一个不带可选参数调用这个函数的例子: ~~~ say('Bob', 'Howdy'); //结果是: Bob says Howdy ~~~ * 下面是用第三个参数调用这个函数的例子: ~~~ say('Bob', 'Howdy', 'smoke signal'); //结果是:Bob says Howdy with a smoke signal ~~~ 3. ***默认参数*** * 函数可以使用=为命名参数和位置参数定义默认值。默认值必须是编译时常量。如果没有提供默认值,则默认值为null。 * 下面是为命名参数设置默认值的示例: ~~~ // 设置 bold 和 hidden 标记的默认值都为false void enableFlags2({bool bold = false, bool hidden = false}) { // ... } // 调用的时候:bold will be true; hidden will be false. enableFlags2(bold: true); ~~~ * 下一个示例显示如何为位置参数设置默认值: ~~~ String say(String from, String msg, [String device = 'carrier pigeon', String mood]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } if (mood != null) { result = '$result (in a $mood mood)'; } return result; } //调用方式: say('Bob', 'Howdy'); //结果为:Bob says Howdy with a carrier pigeon; ~~~ * 您还可以将list或map作为默认值传递。下面的示例定义一个函数doStuff(),该函数指定列表参数的默认list和gifts参数的默认map。 ~~~ // 使用list 或者map设置默认值 void doStuff( {List<int> list = const [1, 2, 3], Map<String, String> gifts = const {'first': 'paper', 'second': 'cotton', 'third': 'leather' }}) { print('list: $list'); print('gifts: $gifts'); } ~~~ 4. ***作为一个类对象的功能*** * 您可以将一个函数作为参数传递给另一个函数。 ~~~ void printElement(int element) { print(element); } var list = [1, 2, 3]; // 把 printElement函数作为一个参数传递进来 list.forEach(printElement); ~~~ * 您也可以将一个函数分配给一个变量。 ~~~ var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!'; assert(loudify('hello') == '!!! HELLO !!!'); ~~~ 5. ***匿名函数*** * 大多数函数都能被命名为匿名函数,如 main() 或 printElement()。您还可以创建一个名为匿名函数的无名函数,有时也可以创建lambda或闭包。您可以为变量分配一个匿名函数,例如,您可以从集合中添加或删除它。 * 一个匿名函数看起来类似于一个命名函数 - 0或更多的参数,在括号之间用逗号和可选类型标注分隔。 * 下面的代码块包含函数的主体: ~~~ ([[Type] param1[, …]]) { codeBlock; }; ~~~ * 下面的示例定义了一个具有无类型参数的匿名函数item,该函数被list中的每个item调用,输出一个字符串,该字符串包含指定索引处的值。 ~~~ var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); }); ~~~ * 如果函数只包含一条语句,可以使用箭头符号=>来缩短它, 比如上面的例2可以简写成: ~~~ list.forEach((item) => print('${list.indexOf(item)}: $item')); ~~~ 6. ***返回值*** * 所有函数都返回一个值,如果没有指定返回值,则语句return null,隐式地附加到函数体。 ~~~ foo() {} assert(foo() == null); ~~~