@@ -681,7 +681,7 @@ Dart有两个运算符,可以让您精确地评估可能需要if-else语句的
681
681
` [] ` |List访问| 引用List中指定索引处的值
682
682
` . ` |成员访问| 指表达的财产; 例如:foo.bar从表达式foo中选择属性栏
683
683
` ?. ` |条件成员访问| 像` . ` 一样,但最左边的操作数可以为空; 例如:` foo?.bar ` 从表达式foo中选择属性` bar ` ,除非foo为空(当foo为空时,foo?.bar的值为空)
684
- ` .. ` |级联符号|级联符号` .. ` 允许您在同一个对象上进行一系列操作。 除了函数调用之外,还可以访问同一对象上的字段。其实相当于java的链式调用。(这个在后面讲类和成员的时候会具体讲解 。)
684
+ ` .. ` |级联符号|级联符号` .. ` 允许您在同一个对象上进行一系列操作。 除了函数调用之外,还可以访问同一对象上的字段。其实相当于java的链式调用。(这个在后面讲 ` 函数 ` 的时候会具体讲解 。)
685
685
686
686
### (九)类型测试操作符:
687
687
@@ -745,11 +745,57 @@ void main() {
745
745
746
746
【注意:】上述代码中的` .. ` 语法称为级联。通过级联,可以对单个对象的成员执行多个操作。
747
747
748
+ 级联符号` .. ` 允许您在同一个对象上进行一系列操作。除了函数调用之外,还可以访问同一对象上的字段。这通常会为您节省创建临时变量的步骤,并允许您编写更流畅的代码。
749
+
750
+ 请看下面的代码:
751
+
752
+ ``` Dart
753
+ querySelector('#confirm') // Get an object.
754
+ ..text = 'Confirm' // Use its members.
755
+ ..classes.add('important')
756
+ ..onClick.listen((e) => window.alert('Confirmed!'));
757
+ ```
758
+
759
+ 第一个方法调用querySelector()返回一个选择器对象。遵循级联表示法的代码对该选择器对象进行操作,忽略可能返回的任何后续值。
760
+
761
+ ** 上述例子相当于:**
762
+
763
+ ``` Dart
764
+ var button = querySelector('#confirm');
765
+ button.text = 'Confirm';
766
+ button.classes.add('important');
767
+ button.onClick.listen((e) => window.alert('Confirmed!'));
768
+ ```
769
+
770
+ ** 级联符号也可以嵌套使用。** 例如:
771
+
772
+ ``` Dart
773
+ final addressBook = (AddressBookBuilder()
774
+ ..name = 'jenny'
775
+
776
+ ..phone = (PhoneNumberBuilder()
777
+ ..number = '415-555-0100'
778
+ ..label = 'home')
779
+ .build())
780
+ .build();
781
+ ```
782
+
783
+ ** 当返回值是` void ` 时不能构建级联。** 例如,以下代码失败:
784
+
785
+ ``` Dart
786
+ var sb = StringBuffer();
787
+ sb.write('foo')
788
+ ..write('bar'); // 这里会报错
789
+ ```
790
+ 上例中的` sb.write() ` 调用返回的是` void ` ,当返回值是` void ` 时不能构建级联。
791
+
792
+ 【注意:】 严格地说,级联的` .. ` 符号不是操作符。它只是Dart语法的一部分。
793
+
748
794
749
795
750
796
### (二)可选参数
751
797
752
- > 可选的命名参数
798
+ > ** 可选的命名参数**
753
799
754
800
定义函数时,使用{param1, param2, …},用于指定命名参数。例如:
755
801
@@ -766,7 +812,7 @@ void enableFlags({bool bold, bool hidden}) {
766
812
enableFlags(bold: true, hidden: false);
767
813
```
768
814
769
- > 可选的位置参数
815
+ > ** 可选的位置参数**
770
816
771
817
包装一组函数参数,用[ ] 它们标记为可选的位置参数:
772
818
@@ -792,7 +838,7 @@ say('Bob', 'Howdy'); //结果是: Bob says Howdy
792
838
say('Bob', 'Howdy', 'smoke signal'); //结果是:Bob says Howdy with a smoke signal
793
839
```
794
840
795
- > 默认参数的值
841
+ > ** 默认参数的值**
796
842
797
843
函数可以使用` = ` 为命名参数和位置参数定义默认值。默认值必须是` 编译时常量 ` 。如果没有提供默认值,则默认值为` null ` 。
798
844
@@ -812,7 +858,20 @@ enableFlags2(bold: true);
812
858
下一个示例显示如何为位置参数设置默认值:
813
859
814
860
``` Dart
861
+ String say(String from, String msg,
862
+ [String device = 'carrier pigeon', String mood]) {
863
+ var result = '$from says $msg';
864
+ if (device != null) {
865
+ result = '$result with a $device';
866
+ }
867
+ if (mood != null) {
868
+ result = '$result (in a $mood mood)';
869
+ }
870
+ return result;
871
+ }
815
872
873
+ //调用方式:
874
+ say('Bob', 'Howdy'); //结果为:Bob says Howdy with a carrier pigeon;
816
875
```
817
876
818
877
您还可以将list或map作为默认值传递。下面的示例定义一个函数` doStuff() ` ,该函数指定列表参数的默认` list ` 和` gifts ` 参数的默认map。
@@ -833,14 +892,178 @@ void doStuff(
833
892
834
893
835
894
836
- ### (三)作为首个类对象的函数
895
+ ### (三)作为一个类对象的功能
896
+
897
+ ** 您可以将一个函数作为参数传递给另一个函数。**
898
+
899
+ 例1:
900
+
901
+ ``` Dart
902
+ void printElement(int element) {
903
+ print(element);
904
+ }
905
+
906
+ var list = [1, 2, 3];
907
+
908
+ // 把 printElement函数作为一个参数传递进来
909
+ list.forEach(printElement);
910
+ ```
911
+
912
+ ** 您也可以将一个函数分配给一个变量。**
913
+
914
+ 例2:
915
+
916
+ ``` Dart
917
+ var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
918
+ assert(loudify('hello') == '!!! HELLO !!!');
919
+ ```
920
+
921
+ 上面例2使用了一个匿名函数。更多关于下一节中的内容:
922
+
923
+
837
924
### (四)匿名函数
925
+
926
+ 大多数函数都能被命名为匿名函数,如` main() ` 或` printElement() ` 。
927
+ 您还可以创建一个名为` 匿名函数 ` 的** 无名函数** ,有时也可以创建** lambda** 或** 闭包** 。
928
+ 您可以** 为变量分配一个匿名函数** ,例如,您可以从集合中添加或删除它。
929
+
930
+ 一个匿名函数看起来类似于一个命名函数 - 0或更多的参数,在括号之间用逗号和可选类型标注分隔。
931
+
932
+ 下面的代码块包含函数的主体:
933
+
934
+ 例1:
935
+
936
+ ``` Dart
937
+ ([[Type] param1[, …]]) {
938
+ codeBlock;
939
+ };
940
+ ```
941
+
942
+ 下面的示例定义了一个具有无类型参数的匿名函数` item ` 。
943
+ 该函数被list中的每个item调用,输出一个字符串,该字符串包含指定索引处的值。
944
+
945
+ 例2:
946
+
947
+ ``` Dart
948
+ var list = ['apples', 'bananas', 'oranges'];
949
+ list.forEach((item) {
950
+ print('${list.indexOf(item)}: $item');
951
+ });
952
+ ```
953
+
954
+
955
+ 如果函数只包含一条语句,可以使用箭头符号` => ` 来缩短它。
956
+
957
+ 比如上面的例2可以简写成:
958
+
959
+ 例3:
960
+
961
+ ``` Dart
962
+ list.forEach(
963
+ (item) => print('${list.indexOf(item)}: $item'));
964
+ ```
965
+
838
966
### _ ~~ (五)语法作用域~~ _
967
+
968
+ Dart是一种具有语法范围的语言,这意味着变量的范围是静态确定的,只需通过代码布局来确定。
969
+ 您可以` 跟随花括号向外 ` 以查看变量是否在范围内。
970
+
971
+ 这里有一个嵌套函数的例子,` 每个作用域级别上都有变量 ` :
972
+
973
+ ``` Dart
974
+ bool topLevel = true;
975
+
976
+ void main() {
977
+ var insideMain = true;
978
+
979
+ void myFunction() {
980
+ var insideFunction = true;
981
+
982
+ void nestedFunction() {
983
+ var insideNestedFunction = true;
984
+
985
+ assert(topLevel);
986
+ assert(insideMain);
987
+ assert(insideFunction);
988
+ assert(insideNestedFunction);
989
+ }
990
+ }
991
+ }
992
+ ```
993
+
994
+ 请注意` nestedFunction() ` 方法中,从每个级别的变量直到顶级,是如何使用的。
995
+
839
996
### _ ~~ (六)语法闭包~~ _
997
+
998
+
999
+ 闭包是一个函数对象,它可以访问其语法范围内的变量,即使函数在其原始范围之外使用。
1000
+
1001
+ 函数可以关闭周围作用域中定义的变量。
1002
+
1003
+ 在下面的示例中,makeAdder()捕获变量addBy。无论返回的函数到哪里,它都会记住addBy。
1004
+
1005
+ ``` Dart
1006
+ ///向函数参数添加[addBy],并返回该函数。
1007
+ Function makeAdder(num addBy) {
1008
+ return (num i) => addBy + i;
1009
+ }
1010
+
1011
+ void main() {
1012
+ var add2 = makeAdder(2);
1013
+
1014
+ var add4 = makeAdder(4);
1015
+
1016
+ assert(add2(3) == 5);
1017
+ assert(add4(3) == 7);
1018
+ }
1019
+ ```
1020
+
840
1021
### (七)测试等式函数
1022
+
1023
+ 下面是一个测试顶级函数、静态方法和相等实例方法的示例:
1024
+
1025
+ ``` Dart
1026
+ void foo() {} // 一个顶级函数
1027
+
1028
+ class A {
1029
+ static void bar() {} //一个静态方法
1030
+ void baz() {} //实例方法
1031
+ }
1032
+
1033
+ void main() {
1034
+ var x;
1035
+
1036
+ // 比较顶级的函数
1037
+ x = foo;
1038
+ assert(foo == x);
1039
+
1040
+ // 比较静态方法
1041
+ x = A.bar;
1042
+ assert(A.bar == x);
1043
+
1044
+ // 比较实例方法
1045
+ var v = A(); // A类的实例1
1046
+ var w = A(); // A类的实例2
1047
+ var y = w;
1048
+ x = w.baz;
1049
+
1050
+ //这些闭包指向同一个实例(#2),所以它们相等。
1051
+ assert(y.baz == x);
1052
+
1053
+ //这些闭包是指不同的实例,所以他们不平等。
1054
+ assert(v.baz != w.baz);
1055
+ }
1056
+ ```
1057
+
841
1058
### (八)返回值
842
1059
1060
+ 所有函数都返回一个值。如果没有指定返回值,则语句return null;隐式地附加到函数体。
843
1061
1062
+ ``` Dart
1063
+ foo() {}
1064
+
1065
+ assert(foo() == null);
1066
+ ```
844
1067
845
1068
# 六、控制流程语句 Control flow statements
846
1069
@@ -866,4 +1089,4 @@ void doStuff(
866
1089
867
1090
# 十七、注释 Comments
868
1091
869
- # 十八、概要 Summary
1092
+ # 十八、概要 Summary
0 commit comments