Flutter大战前夜之Dart语言(上)

版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!

情感语录:时隔悠悠恍如昨; 成家立业各自落。不见当年昔日笑; 结君之情勿淡薄!

Dart预热篇:

Dart是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。Dart诞生于2011年,号称要取代JavaScript。但是过去的几年中一直不温不火。直到Flutter的出现现在被人们重新重视。要学好Flutter的前提我们必须得先会Dart。

官网:https://dart.dev/

Dart环境搭建:要在我们本地开发Dart程序的话首先需要安装Dart Sdk

官方文档:https://dart.dev/get-dart

  windows(推荐):
  
    http://www.gekorm.com/dart-windows/

  mac:

    如果mac电脑没有安装brew这个工具首先第一步需要安装它:  https://brew.sh/brew tap dart-lang/dart
    
    brew install dart

Dart 开发工具: Dart的开发工具有很多: IntelliJ IDEA 、 WebStorm、 Atom、Vscode等

Dart入坑篇之语法:

对于有Java 或kotlin语言基础的同学来说学习Dart将会变得非常得心应手,他既有kotlin中类型推断和丰富的API也具有Java中的写法习惯.且语法也是大同小异。

Dart 语言的关键字:

相比其他语言dart 关键字相对较多几个。

关键字.png

Dart的程序入口:

入口方法的两种定义方式, 和Java 一样程序入口也是 main 方法

 main(){
  //控制台打印输出
  print('你好 dart');
}

//表示无返回值的方法
void main(){
  //控制台打印输出
  print('你好 dart');
  print('你好 dart1');
}
Dart的命名规则:
1、变量名称必须由数字、字母、下划线和美元符($)组成。

2、注意:标识符开头不能是数字

3、标识符不能是保留字和关键字。

4、变量的名字是区分大小写的如: age和Age是不同的变量。在实际的运用中,也建议不要用一个单词大小写区分两个变量。

5、标识符(变量名称)一定要见名思意 :变量名称建议用名词,方法名称建议用动词

实例代码:

void main() {

  //dart里面有类型校验
  //var str='';

  //str=1234; //提示错误
  //print(str);

  String str="2131242";
  print(str);

  int myNum=1243214;
  print(myNum);

  var str1='2134214';

  //var 2str='xxx';   //错误  不能用数字开头

  //var if='124214';  //错误 关键字

  //变量的名字是区分大小写的
  var age=20;

  var Age=30;

  print(age);
  print(Age);


}

输出结果:

2131242
1243214
20
30

Dart 变量:

1、dart是一个强大的脚本类语言,可以不预先定义变量类型 ,自动会类型推断

2、dart中定义变量可以通过var关键字可以通过类型来申明变量

如:

var str='this is var';

String str='this is var';

int str=123;

注意: var 后就不要写类型 , 写了类型 不要var 两者都写 var a int = 5; 报错

Dart 常量: final 和 const修饰符

const 值不变 一开始就得赋值
final 可以开始不赋值 只能赋一次 ; 而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,
即在运行时第一次使用前才初始化

注: 永远不改量的量,请使用final或const修饰它,而不是使用var或其他变量类型。

final name = 'zhengzaihong'; 
final String nickname = 'zzh';

const double PI = 3.1415926;

实例代码:

void main() {

  //var 声明
   var strinfo='你好dart';
   var numinfo=1234;


   print(strinfo);
   print(numinfo);

  //字符串 指定类型声明
   String str='你好dart';
   print(str);
  //数字类型 指定类型声明
   int num=123;
   print(num);

}

结果输出:

你好dart
1234
你好dart
123

Dart中支持以下数据类型:

常用数据类型:

Numbers(数值):
      int
      double
  Strings(字符串)
      String
  Booleans(布尔)
      bool
  List(数组)
      在Dart中,数组是列表对象,所以大多数人只是称它们为列表
  Maps(字典)
      通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个键只出现一次, 而一个值则可以出现多次


 项目中用不到的数据类型:

  Runes 
    Rune是UTF-32编码的字符串。它可以通过文字转换成符号表情或者代表特定的文字。

    main() {
      var clapping = '\u{1f44f}';
      print(clapping);
      print(clapping.codeUnits);
      print(clapping.runes.toList());
    
      Runes input = new Runes(
          '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
      print(new String.fromCharCodes(input));
    }

    
  Symbols
    Symbol对象表示在Dart程序中声明的运算符或标识符。您可能永远不需要使用符号,但它们对于按名称引用标识符的API非常有用,因为缩小会更改标识符名称而不会更改标识符符号。要获取标识符的符号,请使用符号文字,它只是#后跟标识符:


    在 Dart 中符号用 # 开头来表示,入门阶段不需要了解这东西,可能永远也用不上。
    
    http://dart.goodev.org/guides/libraries/library-tour#dartmirrors---reflection
数据类型☞字符串:
 void main() {

  //1、字符串定义的几种方式

   var str1='this is str1';

   var str2="this is str2";

   print(str1);
   print(str2);


   String str3='this is str3';

   String str4="this is str4";

   print(str3);
   print(str4);



   String str5='''
   
   this is str5
   this is str5
   this is str5
   ''';

    print(str5);

    String str6="""
   
   this is str6
   this is str6
   this is str6
   
     """;

    print(str6);



  //2、字符串的拼接

  String str7='你好';

  String str8='Dart';

  print("${str7+str8}"); //支持像kotlin中的${} 字符串模板表达式


  print(str7 + str8);

  print(str7 +" "+ str8);

  //注: 如需要在字符串中保持有换行则需要如下三个双引号或者三个单引号成对出现包裹内容
  //   """ 或者 '''  

}

结果输出:

this is str1
this is str2
this is str3
this is str4
       
       this is str5
       this is str5
       this is str5
       
       
       this is str6
       this is str6
       this is str6
       
         
你好Dart
你好Dart
你好 Dart
数据类型☞数值类型
 void main() {


  //1、int   必须是整型

  int a=123;

  a=45;

  print(a);

  //2、double  既可以是整型 也可是浮点型

  double b=23.5;


  print(b);

  //3、运算符

  // + - * / %

  var c=a+b;
  print(c);


}

结果输出:

45
23.5
68.5
数据类型☞布尔类型
void main() {

   // 1、bool 支持java中的三目运算符
  var flag=true;
  var str = flag?"真":"假";
  print(str);


  //2、条件判断语句
  var a=123;
  var b=123;

  if(a==b){
    print('a=b');
  }else{
    print('a!=b');
  }

}

结果输出:

真
a=b
数据类型☞List(数组/集合)
void main() {

  //1、第一种定义List的方式

  var list1=['aaa','bbbb','cccc'];

  print(list1);

  print(list1.length);

  print(list1[1]); //取出下标为1的元素


  //2、第二种定义List的方式,用法和java中List 没什么区别

  var list2=new List();

  list2.add('张三');
  list2.add('李四');
  list2.add(1);
   print(list2);


  //3、定义List指定类型

  var list3=new List();

  list3.add('张三');

  //list3.add(123);//提示不支持的数据类型

  print(list3);
}

输出结果:

[aaa, bbbb, cccc]
3
bbbb
[张三, 李四, 1]
[张三]
数据类型☞Maps(字典)
void main() {

  //第一种定义 Maps的方式,如json 格式的键值对

   var person={
     "name":"张三",
     "age":20,
     "work":["程序员","送外卖"]
   };

   print(person);

   print(person["name"]);//通过key 取value


   print("-----------------");

  //第二种定义 Maps的方式 如java中map.put(key,value)

  var p=new Map();

  p["name"]="李四";
  p["age"]=22;
  p["work"]=["程序员","送外卖"];
  print(p);

  print(p["age"]);//通过key 取value

}

结果输出:

{name: 张三, age: 20, work: [程序员, 送外卖]}
张三
-----------------
{name: 李四, age: 22, work: [程序员, 送外卖]}
22
Dart判断数据类型 :

Java中判断数据类型的关键字 ' instanceof ' ,Dart和kotlin一致都是使用 ' is ' 关键字判断

void main() {

  var str=123;

  if(str is String){
    print('是string类型');
  }else if(str is int){
    print('是int类型');
  }else{
    print('其他类型');
  }
  
  //输出结果:是int类型

}

Dart运算符和类型转换

1、Dart运算符:
算术运算符

  +    -    *    /     ~/ (取整)     %(取余)
  
关系运算符

  ==    !=   >    <    >=    <=

逻辑运算符

    !  &&   ||

赋值运算符

 基础赋值运算符   =   ??=    ++  --
 复合赋值运算符   +=  -=  *=   /=   %=  ~/=


条件表达式 

    if  else   switch case 

    三目运算符

    ??运算符:


void main() {

  int a=13;
  int b=5;

  print(a+b);   //加    18
  print(a-b);   //减    8
  print(a*b);   //乘    65
  print(a/b);   //除    2.6
  print(a%b);   //其余  3
  print(a~/b);  //取整  2

  var c=a*b;
  print('--------');
  print(c);     //      65


  int e=5;
  int f=3;

  print(e==f);   //判断是否相等       false
  print(c!=b);   //判断是否不等       true
  print(e>f);    //判断是否大于       true
  print(e=f);   //判断是否大于等于    true
  print(e<=f);   //判断是否小于等于    false


  if(e>f){
    print('e大于f');    //输出 :e大于f
  }else{
    print('e小于f');
  }

  /* ! 取反 */

   bool flag=false;
   print(!flag);   //取反    true


  /* &&并且:全部为true的话值为true 否则值为false */

   bool a1=true;
   bool b1=true;

   print(a1 && b1);    //true


  /* ||或者:全为false的话值为false 否则值为true */

   bool a2=false;
   bool b2=false;

   print(a2 || b2);   //false


  //1、  基础赋值运算符   ??=    ++  --

   int w =0;

   w??=23;  //表示如果w为空的话把 23赋值给w 这功能很优秀o((≧▽≦o)

   print(w); //输出 0

  var q;
  var j= q ?? 10;

  print(j);  // 10

  // ++  --   表示自增 自减 1
  // 在赋值运算里面 如果++ -- 写在前面 这时候先运算 再赋值,如果++ --写在后面 先赋值后运行运算
  
  // 注:同名成员变量只能定义一次,方便观看后面的并未注释掉.实际是不可以的哟
  var k=10;
  var g=k--;

  print(k);  //9
  print(g);  //10

  var k=10;
  var g=k++;

  print(k);  //11
  print(g);  //10


  var k=10;
  var g=++k;

  print(k);  //11
  print(g);  //11

  var k=10;
  var g=--k;

  print(k);  //9
  print(g);  //9


  //2、  复合赋值运算符   +=  -=  *=   /=   %=  ~/=

   var y=12;

   y=y+10;

   print(y); // 22

   var z=13;
   z+=10;   //表示z=z+10
   print(z);  // 23

   var h=4;

   h*=3;  //h=h*3;

   print(h); // 12



  //1、条件表达式: if  else   switch case

  //判断一个人的成绩 如果大于60 显示及格   如果大于 70显示良好  如果大于90显示优秀
   var score=41;
   if(score>90){
     print('优秀');
   }else if(score>70){
      print('良好');
   }else if(score>=60){
     print('及格');
   }else{
     print('不及格');  // 输出 不及格
   }


  //2、三目运算符:上面已经讲到过, 不再坠述


}
2、类型转换
1、Number与String类型之间的转换

2、其他类型转换成bool类型

 void main() {

  //1、Number与String类型之间的转换

  // Number类型转换成String类型 toString() 和java 以及kotlin一致

  // String类型转成Number类型  int.parse()  java中事通过封装类转换如:Integer.parseInt() 而kotlin中 是通过toInt() 如 "123".toInt()

   String str='123';
   var num=int.parse(str);

   print(num is int);  // true


   String str1='123.1';

   var num1=double.parse(str1);

   print(num1 is double); // true


   String price='12';

   var num2=double.parse(price);

   print(num2);

   print(num2 is double); // true


  //报错   try  ... catch 捕获异常,和java,kotlin 使用一样

    String prices='';
     try{
       var num2=double.parse(prices);

       print(num2);
     }catch(err){
          print(0);  //  输出 0
     }

   var num3=12;

   var str2=num3.toString();

   print(str2 is String); // true


  // 2、其他类型转换成Booleans类型

  // isEmpty:判断字符串是否为空

   var str3='';
   if(str3.isEmpty){
     print('str3空');// 输出 str3空
   }else{
     print('str3不为空');
   }

   var myNum;

   if(myNum==0){
      print('0');
   }else{
     print('非0'); // 输出 非0
   }

   var value;
   if(value==null){
      print('空'); // 输出 空
   }else{
     print('非空');
   }

  var myNum1=0/0;
  if(myNum1.isNaN){
    print('NaN'); // 输出 NaN
  }


}

Dart中的循环:

1、Dart中for循环:
    //for基本语法

    for (int i = 1; i<=100; i++) {   
        print(i);
      }

    //第一步,声明变量int i = 1;
    //第二步,判断i <=100
    //第三步,print(i);
    //第四步,i++
    //第五步 从第二步再来,直到判断为false
2、Dart中while循环:
    //语法格式:
    
    while(表达式/循环条件){            
        
    }   
    
        
    do{
        语句/循环体
        
    }while(表达式/循环条件);
    
            

    //注意: 1、最后的分号不要忘记
    //       2、循环条件中使用的变量需要经过初始化
    //       3、循环体中,应有结束循环的条件,否则会造成死循环。
3、Dart中的break和continue流程控制:
/*
    break语句功能:
      1、在switch语句中使流程跳出switch结构。
      2、在循环语句中使流程跳出当前循环,遇到break 循环终止,后面代码也不会执行
      
      强调:
      1、如果在循环中已经执行了break语句,就不会执行循环体中位于break后的语句。
      2、在多层循环中,一个break语句只能向外跳出一层

    break可以用在switch case中 也可以用在 for 循环和 while循环中

    continue语句的功能:
          
    【注】只能在循环语句中使用,使本次循环结束,即跳过循环体重下面尚未执行的语句,接着进行下次的是否执行循环的判断。

    continue可以用在for循环以及 while循环中,但是不建议用在while循环中,不小心容易死循环
*/

Dart中的循环和Java和kotlin都是一直,其他语言也是类似,没什么好讲的,这里就不举例了!

Dart中集合类型List Set Map详解 以及循环语句:

1、Dart中的List:

List里面常用的属性和方法:

常用属性:
    length          长度
    reversed        翻转
    isEmpty         是否为空
    isNotEmpty      是否不为空
常用方法:  
    add         增加
    addAll      拼接数组
    indexOf     查找  传入具体值
    remove      删除  传入具体值
    removeAt    删除  传入索引值
    fillRange   修改   
    insert(index,value);            指定位置插入    
    insertAll(index,list)           指定位置插入List
    toList()    其他类型转换成List  
    join()      List转换成字符串
    split()     字符串转化成List

   注:以下是集合的通用用法,放在后面单独讲。

    forEach     循环;同java 和kt中一样
    map         如kotlin和JDK1.8以上中一样 可以看做类型转换
    where       集合中条件查询
    any         集合中有一个满足条件既返回真
    every       每一个都满足条件返回true  否则返回false




void main() {

   List fruits=['香蕉','苹果','西瓜'];
   print(fruits[1]); // 打印数组: ['香蕉','苹果','西瓜']


   var list=new List();
   list.add('111');
   list.add('222');
   print(list); // 输出:[111, 222]


   //List里面的属性:
   List fruits1=['香蕉','苹果','西瓜'];
   print(fruits1.length);        // 3
   print(fruits1.isEmpty);       //false
   print(fruits1.isNotEmpty);    //true
   print(fruits1.reversed);      //对列表倒序排序 // (西瓜, 苹果, 香蕉)
   var newMyList=fruits1.reversed.toList();
   print(newMyList);

   
  //List里面的方法:

   List fruits2=['香蕉','苹果','西瓜'];
   fruits2.add('桃子');   //增加数据  增加一个

   fruits2.addAll(['桃子','葡萄']);  //拼接数组

   print(fruits2); // 输出:[香蕉, 苹果, 西瓜, 桃子, 桃子, 葡萄]

   print(fruits2.indexOf('苹x果'));    //indexOf查找数据 查找不到返回-1  查找到返回索引值


   fruits2.remove('西瓜');

   fruits2.removeAt(1);

   print(fruits2); // 输出:[香蕉, 桃子, 桃子, 葡萄]


   List fruits3=['香蕉','苹果','西瓜'];

   fruits3.fillRange(1, 2,'aaa'); //修改:将下标为1开始的元素到下标为2的元素修改为 'aaa',注意这里是前闭后开区间,[ )
                                  // 既不会取到2的元素,下标越界会抛出 RangeError 异常。
                                  // 此时结果['香蕉','aaa','西瓜']

   fruits3.insert(1,'aaa');      //插入一个元素,此时结果:['香蕉','aaa',,'aaa','西瓜']

   fruits3.insertAll(1, ['aaa','bbb']);  //插入多个元素

   print(fruits3);  //结果:[香蕉, aaa, bbb, aaa, aaa, 西瓜]



   List fruits4=['香蕉','苹果','西瓜'];

   var str=fruits4.join('-');   //list转换成字符串,可以理解是java中的循环取出每一个元素然后字符串拼接或者StringBuffer等方式

   print(str);  //输出:香蕉-苹果-西瓜

   print(str is String);  // true


  var str1='香蕉-苹果-西瓜';

  var list1=str1.split('-');// "按照 '-' 进行分割后返回一个数组:好比Java中:String[] array = str1.split('-')一样"

  print(list1); // 输出:[香蕉, 苹果, 西瓜]

  print(list1 is List); // true


}
2、Dart中的Set:

1、用它最主要的功能就是去除数组重复内容

2、Set是没有顺序且不能重复的集合,所以不能通过索引去获取值

void main() {

   var set=new Set();
   set.add('香蕉');
   set.add('苹果');
   set.add('苹果');

   print(set);   //{香蕉, 苹果}

   print(set.toList()); // [香蕉, 苹果]


  List myList=['香蕉','苹果','西瓜','香蕉','苹果','香蕉','苹果'];

  var s=new Set();

  s.addAll(myList); 

  print(s);// {香蕉, 苹果, 西瓜} 可以看出Set会自动帮我去除重复元素

  print(s.toList()); //[香蕉, 苹果, 西瓜]


}
2、Dart中的Map:

Map创建的两种方式:

1、静态创建并赋值

2、通过关键字new 一个Map 创建,可动态添加删除等(通常使用这种方式)

      映射(Maps)是无序的键值对:
    
        常用属性:
            keys            获取所有的key值
            values          获取所有的value值
            isEmpty         是否为空
            isNotEmpty      是否不为空
        常用方法:
            remove(key)     删除指定key的数据
            addAll({...})   合并映射  给映射内增加属性
            containsValue   查看映射内的值  返回true/false
   
void main() {

   //静态创建并赋值
   Map person={
     "name":"张三",
     "age":20
   };

   //通过关键字new 创建,可动态添加删除等
   var m=new Map();
   m["name"]="李四";

   print(person); // 输出:{name: 张三, age: 20}
   print(m);  // 输出:{name: 李四}

   //常用属性:

   Map person1={
     "name":"张三",
     "age":20,
     "sex":"男"
   };

   print(person1.keys.toList());  // 输出:[name, age, sex]
   print(person1.values.toList()); // 输出:[张三, 20, 男]
   print(person1.isEmpty); //false
   print(person1.isNotEmpty); //true


  //常用方法:
  Map person2={
    "name":"张三",
    "age":20,
    "sex":"男"
  };

   person2.addAll({
     "work":['敲代码','送外卖'],
     "height":160
   });

   print(person2); // 输出:{name: 张三, age: 20, sex: 男, work: [敲代码, 送外卖], height: 160}

   person2.remove("sex");
   print(person2);// 输出:{name: 张三, age: 20, work: [敲代码, 送外卖], height: 160}

  print(person2.containsValue('张三')); //true

}
Dart中集合的高阶用法( forEach 、map 、 where 、 any、every):
void main() {


   //list 相关
   List myList1=['香蕉','苹果','西瓜'];

   //普通for循环
   for(var i=0;i
   var newNumbers=numbers.map((value){
       return value*2;
   });
   // 转换成 List集合
    print(newNumbers.toList());  // [2, 6, 8]



   List numbers1=[1,3,4,5,7,8,9];

   // 使用where 查询满足条件的元素后得到一个新的Iterable
   var newNumbers1=numbers1.where((value){
       return value>5;
   });
   // 转换成 List集合
   print(newNumbers1.toList());  // [7, 8, 9]


   List myList=[1,3,4,5,7,8,9];

   //只要集合里面有满足条件的就返回true
   var f=myList.any((value){

       return value>5;
   });
   print(f); //true


   //每一个都满足条件返回true  否则返回false
   var flag=myList.every((value){

       return value>5;
   });
   print(flag); //false




   //set 相关

   var set=new Set();

   //添加一个list
   set.addAll([1,222,333]);

   //遍历输出
   set.forEach((value)=>print(value));


   //注意:set 为无序不重复集合,不能像List中通过for循环下标去取值。除了用forEach外我们还可以像
   // Java中的 迭代器(Iterator)遍历去取值 如下:

   Iterator iterable =  set.iterator;
   while(iterable.moveNext()){
     print(iterable.current); // 结果和 forEach 是一样的
   }


  //map 相关

  Map person={
    "name":"张三",
    "age":20
  };

   // 分别取出key 和value,这和kt中一样,但相比Java 简单许多
  person.forEach((key,value){
    print("$key---$value");
  });
}

Dart中的变量和方法以及作用域:

1、变量的定义和作用域:

1.方法体内的成员变量;隶属于方法,既在该方法体以及子方法里可以使用。

2.类成员变量;隶属于该类,既在该类下都可以使用。

3.全局成员变量;隶属于整个应用。

实例代码:

//创建一个全局变量
var shardInfo = "the life cycle is appliction";

//创建一个类(后面章节会讲到,看不懂无所谓)
class TestClass{

  // 类成员变量
  var variables = "2";

}

main(){
   //局部成员变量
   int age = 18;
    print(age);
}
2、方法的定义和作用域:

方法的作用域:

1、方法体内的方法;隶属于该方法,既在该方法体以及子方法里可以调用。

2、类中的方法;隶属于该类,既在该类里可以调用或者通过 new 创建对象后调用。

3、全局方法:隶属应用,可以看做是在任何地方都能调用。

4、匿名方法:依赖与接收者(句柄)的作用域(后面会讲到)

方法的声明:

    内置方法/函数:

      print();

  自定义方法:
      自定义方法的基本格式:

      返回类型  方法名称(参数1,参数2,...){
        方法体
        return 返回值;
      }

注意:
① 在Dart中方法的返回类型和行参是不必须明确指定的,但在开发中应需遵守代码规范,所以应该明确写出接收值类型防止误操作和传参错误等!

② 在Dart语言中方法体内是还可以定义方法的,像kotlin中一样。这个一定得和Java区别开来。

实例代码:

 //全局方法
void login(String phone,String pass){
     print("${"手机号:"+phone+"  密码:"+pass}");
}

class TestClass{

  var name;
  //类方法
  void setName(String name){
    this.name = name;
  }
}

//演示方法的作用域
void main(){

  //方法体中的方法
  int getAge(){
    var age=18;
    return age;
  }

  String printUserInfo(){
    getAge();
    return 'this is userInfo';
  }
   print(printUserInfo());

  void action(){
    //在方法体内定义方法
    move(){
      print(printUserInfo());
    }

    move();
  }
   //move();  //错误写法 move()方法的作用域只能在action()方法内调用

  action();   //调用方法


}

Dart中的方法成参数:

方法的参数(行参)介绍:

1、行参可以不用写明参数类型,为了可读性和代码规范应该写出行参类型

2、可选参数使用[]进行定义,多个参数使用","分割开 如:[int age,String sex]

3、默认参数也是使用[]进行定义,顾名思义既在没有传入该值是使用默认给出的值 如:[String sex='男',int age]

4、命名参数是有{}进行定义,既在调用时必须指定名称和方法中行参名保持一致 如:{int age,String sex='男'}

5、行参接收一个方法,在参数列表中不能写参数类型!行参名随便定义(需见名知意),调用方式 行参名( )

实例代码:

void main(){

   //1、定义一个没有指定返回类型和接收参数的方法

    printUserInfo(username, age){  //行参
       return "姓名:$username---年龄:$age";
   }

   print(printUserInfo('张三',20)); //实参 //输出:姓名:张三---年龄:20


    //2、定义一个带可选参数的方法

   String printUserInfo2(String username,[int age]){  //行参

     if(age!=null){
       return "姓名:$username---年龄:$age";
     }
     return "姓名:$username---年龄保密";

   }

   print(printUserInfo2('张三',21));  // 姓名:张三---年龄:21

   print(printUserInfo2('张三'));  // 姓名:张三---年龄保密



    //3、定义一个带默认参数的方法

   String printUserInfo3(String username,[String sex='男',int age]){  //行参

     if(age!=null){
       return "姓名:$username---性别:$sex--年龄:$age";
     }
     return "姓名:$username---性别:$sex--年龄保密";

   }

   print(printUserInfo3('张三')); //姓名:张三---性别:男--年龄保密

   print(printUserInfo3('小李','女')); //姓名:小李---性别:女--年龄保密

   print(printUserInfo3('小李','女',30));//姓名:小李---性别:女--年龄:30


  //4、定义一个命名参数的方法

   String printUserInfo4(String username,{int age,String sex='男'}){

       if(age!=null){
         return "姓名:$username---性别:$sex--年龄:$age";
       }
       return "姓名:$username---性别:$sex--年龄保密";

   }
   print(printUserInfo4('张三',age:20,sex:'未知')); //姓名:张三---性别:未知--年龄:20

  //5、实现一个把方法当做参数的方法

  action(){

    print('this is action');
  }
  action2(fn){

    fn(); // 这里fn() 其实就是action(),这里理解可能有点抽象
  }

  //调用action2这个方法 把action这个方法当做参数传入
  action2(action);

}

Dart中特别的方法:

1、匿名方法,既没有定义方法名

2、自执行方法,定义格式((行参....){ 方法体 })(实参)

实例代码

//相当于上面讲的全局方法,作用域在整个应用
var action;

void main(){

  //匿名方法
  action=(){
     print(123);
   };

  action();


 var action1=(){
    print(123);
  };

  action1();


 //自执行方法
   ((int age){
     print("我今年${age}岁");
   })(18);


 //方法的递归 求1-100的和  递归好像没啥特别的,这里只是介绍下
  var sum=0;
  fn(int n){
    sum+=n;
    if(n==0){
      return;
    }
    fn(n-1);
  }

  fn(100);
  print(sum);

}

Dart中的闭包:

1、全局变量特点: 全局变量常驻内存、全局变量污染全局

2、局部变量的特点: 不常驻内存会被垃圾机制回收、不会污染全局

【注】我想实现的功能: 常驻内存且不污染全局怎么办?于是Dart中产生了闭包。

闭包:函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)

闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包。

实例代码:

void main(){

  action(){
    //不会污染全局   常驻内存
    var a=123;
    return(){
      a++;
      print(a);
    };
  }
  var b=action();
  b(); // 调用输出结果:124
  b(); // 调用输出结果:125

}

由于篇幅问题,涉及到的知识点也挺多,对于没有语言基础的同学吸收起来可能要花上些时间,如果你有像Java或Kotlin语言基础的应该是很快就能上手,好了本篇点到为止就此结束。谢谢大家观看,下篇内容更精彩,再会!!!!!!

你可能感兴趣的:(Flutter大战前夜之Dart语言(上))