Dart 语言基础入门篇( 三 )


enableFlags(false, true);你可以使用[]来增加非必填参数:
void enableFlags(bool bold, bool hidden, [bool option]) {}另外,Dart 的函数还支持设置参数默认值:
void enableFlags({bool bold = false, bool hidden = false}) {...}String say(String from, [String device = 'carrier pigeon', String mood]) {}匿名函数顾名思意,匿名函数的意思就是指没有定义函数名的函数 。你应该对此不陌生了,我们在遍历List和Map的时候已经使用过了,通过匿名函数可以进一步精简代码:
var list = ['apples', 'bananas', 'oranges'];list.forEach((item) {print('${list.indexOf(item)}: $item');});闭包Dart支持闭包 。没有接触过JavaScript的同学可能对闭包(closure)比较陌生,这里给大家简单解释一下闭包 。
闭包的定义比较拗口,我们不去纠结它的具体定义,而是打算通过一个具体的例子去理解它:
Function closureFunc() {var name = "Flutter"; // name 是一个被 init 创建的局部变量void displayName() { // displayName() 是内部函数,一个闭包print(name); // 使用了父函数中声明的变量}return displayName;}void main(){//myFunc是一个displayName函数var myFunc = closureFunc(); //(1)// 执行displayName函数myFunc(); // (2)}结果如我们所料的那样打印了Flutter 。
在(1)执行完之后,name作为一个函数的局部变量,引用的对象不是应该被回收掉了吗?但是当我们在内函数调用外部的name时,它依然可以神奇地被调用,这是为什么呢?
这是因为Dart在运行内部函数时会形成闭包,闭包是由函数以及创建该函数的词法环境组合而成,这个环境包含了这个闭包创建时所能访问的所有局部变量  。
我们简单变一下代码:
Function closureFunc() {var name = "Flutter"; // name 是一个被 init 创建的局部变量void displayName() { // displayName() 是内部函数,一个闭包print(name); // 使用了父函数中声明的变量}name = 'Dart'; //重新赋值return displayName;}结果输出是Dart,可以看到内部函数访问外部函数的变量时,是在同一个词法环境中的 。
返回值在Dart中,所有的函数都必须有返回值,如果没有的话,那将自动返回null:
foo() {}assert(foo() == null);流程控制这部分和大部分语言都一样,在这里简单过一下就行 。
if-elseif(hasHause && hasCar){marry();}else if(isHandsome){date();}else{pass();}循环各种for:
var list = [1,2,3];for(var i = 0; i != list.length; i++){}for(var i in list){}while和循环中断(中断也是在for中适用的):
var i = 0;while(i != list.length){if(i % 2 == 0){continue;}print(list[i]);}i = 0;do{print(list[i]);if(i == 5){break;}}while(i != list.length);如果对象是Iterable类型,你还可以像Java的 lambada 表达式一样:
list.forEach((i) => print(i));list.where((i) =>i % 2 == 0).forEach((i) => print(i));switchswitch可以用于int、double、String 和enum等类型,switch 只能在同类型对象中进行比较,进行比较的类不要覆盖==运算符 。
var color = '';switch(color){case "RED":break;case "BLUE":break;default:}assert在Dart中,assert语句经常用来检查参数,它的完整表示是:assert(condition, optionalMessage),如果condition为false,那么将会抛出[AssertionError]异常,停止执行程序 。
assert(text != null);assert(urlString.startsWith('https'), 'URL ($urlString) should start with "https".');assert 通常只用于开发阶段,它在产品运行环境中通常会被忽略 。在下面的场景中会打开assert:

  1. Flutter 的 debug mode 。
  2. 一些开发工具比如dartdevc默认会开启 。
  3. 一些工具,像dart 和dart2js ,可以通过参数--enable-asserts 开启 。
异常处理Dart 的异常处理和Java很像,但是Dart中所有的异常都是非检查型异常(unchecked exception),也就是说,你不必像 Java 一样,被强制需要处理异常 。
Dart 提供了Exception 和 Error 两种类型的异常 。一般情况下,你不应该对Error类型错误进行捕获处理,而是尽量避免出现这类错误 。
比如OutOfMemoryError、StackOverflowError、NoSuchMethodError等都属于Error类型错误 。
前面提到,因为 Dart 不像 Java 那样可以声明编译期异常,这种做法可以让代码变得更简洁,但是容易忽略掉异常的处理,所以我们在编码的时候,在可能会有异常的地方要注意阅读API文档,另外自己写的方法,如果有异常抛出,要在注释处进行声明 。比如类库中的File类其中一个方法注释:


推荐阅读