flutter Dart语法

Dart语言特点:

     Dart中,一切(数字类型、方法、null等)都是对象,一切对象都是class的实例,所有的对象都是继承自Object
     Dart支持范型,List<int>表示一个整型的数据列表,List<dynamic>则是一个对象的列表,其中可以装任意对象
     Dart支持顶层方法(如main方法),也支持类方法或对象方法,同时你也可以在方法内部创建方法
     Dart支持顶层变量,也支持类变量或对象变量
     Dart没有public protected private等关键字,
     Dart中若某个变量以下划线_ 开头,代表这个变量在库中是私有的

打印语法:

     print(#s == new Symbol("s"));// 打印:true
     var clapping = '\u{1f44f}';
     print(clapping); // 打印的是拍手emoji的表情
     print(add(1,1)); // 打印 调用函数 的返回值
     sayHello({String name}) {
          print("这是一个有 命名参数的函数: $name"); //打印函数的参数
     }

一、变量与常量

变量声明与默认值:没有赋初值的变量都会有默认值null
     int b = 10;
     String s = "hello"; 
     var a = 1; //变量,自动推断其数据类型
     dynamic c = 0.5;  //对象,自动推断其数据类型
final 和 const
     var count = 10; 
     const Num1 = 10; // const赋值必须是编译时常量,编译时就确定值了
     final Num2 = count;  // final 只能赋值一次,赋的值不一定是编译时常量;在运行时第一次使用前才初始化

二、数据类型

数字:
     var a = 0;
     int b = 1;
     double c = 0.1;
字符串:
     var s1 = 'hello';
     String s2 = "world";
布尔:
     var real = true;
     bool isR = false;
数组:
     var arr = [1, 2, 3, 4, 5]; //自动推断为 数字数组
     List<String> arr2 = ['hello', 'world', "123", "456"]; //字符串数组
     List<dynamic> arr3 = [1, true, 'haha', 1.0];//对象数组
字典:
     var map = new Map();
     map['name'] = 'zhangsan';
     map['age'] = 10;
     Map m = new Map();
     m['a'] = 'a';
字符集: runes
     Dart 中 使用runes 来获取UTF-32字符集的字符。
     String的 codeUnitAt and codeUnit属性可以获取UTF-16字符集的字符
     var clapping = '\u{1f44f}';
     print(clapping); // 打印的是拍手emoji的表情
符号: symbols:
     print(#s == new Symbol("s"));// 打印:true

三、函数

Dart中的函数也有一种类型 Function,函数可以作为参数传递,也可以赋值给某个变量;
1.函数的返回值
     //声明函数返回值类型
     int add(int a, int b){
          return a + b;
     }
     //不声明函数返回值类型
     add2(int a, int b){
          return a + b;
     }
     // return 返回语句的简写: =>
     add3(a,b) => a + b;
     //函数的调用
     main(){
          print(add(1,1)); // 2
          print(add2(1,2)); // 3
          print(add3(1,3)); // 4
     }
2.函数的参数:
     //===============命名参数===============
     sayHello1({String name}) {
          print("这是一个有 命名参数的函数: $name");
     }
     sayHello2({name: String}) {
          print("带 命名参数 的函数的第二种写法:$name");
     }
     sayHello3({@required String name}) {
          print("必须穿参数,否则报错:$name");
     }
     main(){
          sayHello1(name:'张三'; // 这是一个有 命名参数的函数:张三
          sayHello2(name:'李四'); // 带 命名参数 的函数的第二种写法: 李四
          sayHello2();// 没有传参数,此时打印: 带 命名参数 的函数的第二种写法:null
          sayHello3();// 不传参数 会报错
     }
     //===============位置参数===============
     //位置参数用[] 包裹,可传可不传,放在参数列表的最后,可以是多个
     sayHello(String name, int age, [String a, int b]){ 
          StringBuffer sb = new StringBuffer(); // 可变字符串
          sb.write("名字: $name  年龄:$age");
          if(a != null){
               sb.write("这是a: $a");
          }
          print(sb.toString());
     }
     main(){
          sayHello("张三",20); // 打印: 名字:张三 年龄:20
          sayHello("张三",20,"糖"); // 打印: 名字:张三 年龄:20 这是a:糖
     }
     //===============参数默认值===============
     int add({int a, int b=3}){ //不能写成 int add({a: int, b: int = 3})
          return a + b;
     }
     int sum(int a, int b, [int c=3]){
          return a + b + c;
     }
     main{
          print(add(1)); // 4 (?)
          print(sum(1,1)); // 5 (?)
     }
3.main()函数:
     main()函数,应用入口函数,返回值是 void ,有一个可选参数,参数类型是List<String>
     1.函数作为参数传递给另一个函数
          printNum(int a){
               print("$a");
          }
          main(){
               var arr = [1,2,3];
               arr.forEach(printNum);//将数组中的每一个元素都依次传入函数printNum中,依次打印:1、2、3
          }
     2.函数赋值给某个变量
          printNum(int a){
               print("$a");
          }
          main(){
               var f1 = printNum;
               Function f2 = printNum;
               var f3 = (int a) => print("a = $a");
               f1(1); // 1
               f2(2); // 2
               f3(6); // a = 6
          }
     3.匿名函数
          没有名称的函数,类似于Java中的接口,一般在某个函数的参数为函数时使用到
          test(Function callback) {
               callback("hello"); // callback就是一个匿名函数
          }
          main(){
               test((param){
                    print(param);//打印 hello
               });
          }
     4.函数返回值
          所有的函数都有返回值,如果没有指定return语句,那么该函数的返回值为null

四、运算符

运算符优先级: 每个运算符的优先级 都高于 后面行中的运算符。
main(){
//================与java相同的运算符操作================
     var  a,b;
     a = 0;
     b = ++a; // a:1 b:1   ++a 先++ 再赋值
     b = a++; // a:2 b:1   a++ 先赋值 后++
     print(a==b); // false
     print(a*b);//2
     bool real = false;
     real ? print("真") : print("非真") // 非真
     print(real && a== b);// false
     print (real || a == 2);// true
     print(a !=3); // true
     print(a <= b); // false
     var c = 9;
     c += 10;
     print("c = $c"); // c = 19
     print(1<<2); // 4  左移运算符:将1的二进制向左移2位,变为100(十进制 4)
     print(4>>2); // 1  右移运算符:将4的二进制向右移2位,变为1
//================与java不同的运算符操作================
     1. is 与 is!
          var s = "hello";
          var num = 6;
          print(s is String); // true    is运算符用于判断变量是某个类型的数据
          print(num is! String); // true  is!运算符用于判断变量不是某个类型的数据
     2. 除法 与取整
          int k = 1;
          int j = 2;
          print(k / j); // 0.5   '/'运算符 是 除法运算 ,不取整
          print(k ~/ j); // 0    '~/'运算符 取整
     3.强制类型转换
          //as 运算符 将对象转换为特定类型
          if(emp is Person){ //如果 emp 是 Person 类型  赋值
               emp.firstName = "ABC";
          }
          //如果 emp 不是 person类型 或为 空,上面什么都不做
          //下方代码:如果emp为空 或不是Person类型,将抛出异常;如果emp是Person类型,给其赋值;
          (emp as Person).firstName = "ABC"; 
     4.为null时赋值
          var p1 = "hello", p2 = null;
          p1 ??= "world"; // 若 p1 为 null 则赋值,否则 不赋值
          p2 ??= "world"; // 若 p2 为 null 则赋值,否则 不赋值
     5.属性为空的判断
          var str1 = "hello", str2 = null;
          print(str1?.length); // 5  若 str1 有length 属性 则忽略'?'的作用
          print(str2?.length); // null 若 str2 没有length的属性 则返回null
          print(str2.length); // 报错
     6.级联操作(.. 运算符)
          使用'..'运算符调用对象的方法或成员变量,可以连续使用'..'运算符;但不能再返回 void 上构造级联
          示例:
               var button = queaySelector('#confirm');
               button.text = 'Confirm';
               button.classes.add('important');
               button.onClick.listen((e) => window.alert('Confirmed!'));
          等价于:
               querySelector('#confirm')
                    ..text = 'Confirm'
                    ..classes.add('important')
                    ..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,在void上构造级联会报错
               var sb = StringBuffer();
               sb.write('foot') // 此时返回void
                    ..write('bar'); //在void上构造级联会报错
}

五、控制流程

main(){
     1. if-else语句
          int score = 80;
          if(score < 60){
               print("不及格");
          }else if(score >= 60 && score < 80){
               print("良好");
          }else{
               print("优秀");
          }
     2. switch语句
          String a = "hello";
          switch (a) {
               case "hello": // case 语句中的数据类型必须跟switch中的类型一致
                    print("是hello");
               break;
               case "world":
                    print("是world");
               break;
               default:
                    print("其他");
          }
     3. for 语句 (for-in)
          List<String> list = ["a","b","c"];
          for (int i = 0; i < list.length; i++){
               print(list[i]);
          }
          for (var i in List){
               print (i);
          }
     4. while 语句
          int start = 1;
          int sum = 0;
          while(start <= 100){
               sum += start;
               start++;
          }
          print(sum);
     5. try catch 语句
          try{
               pring(1 ~/ 0);
          } catch(e){
               print(e);
          }
          try{
               1 ~/ 0;
          } on IntegerDivisionByZeroException { // 铺货指定类型的异常
               print("error");
          } finally{
               print("over");
          }
}

六、类

Dart中的类没有 private/protected/public等访问控制,
1.类的定义
     class Person{
          //3个成员变量
          String name;
          int age;
          String gender;

          //1个构造方法
          Person(this.name,this.age,this.gender);
          //上方的构造方法 写法上等同于:
          Person(String name, int age, String gender){
               this.name = name;
               this.age = age;
               this.gender = gender;
          }

          //1个成员方法 : 成员方法是一个函数,为该类提供某些行为
          sayHello(){
               print("我叫 $name, 今年 $age岁,性别 $gender");
          }
     }
2.调用 Person 类的成员变量或成员方法
     var p = new Person("张三",22,"男");
     p.sayHello(); // 打印: 我叫 张三, 今年 22岁,性别 男
     p.age = 25;
     p.gender = "女";
     p.sayHello(); // 打印:我叫 张三, 今年 25岁,性别 女
3.类的命名构造方法
     class Point{
          num x,y;
          Point(this.x,this.y);
          //类的命名构造方法
          Point.origin(){
               x=0;
               y=0;
          }
     }
     main(){
          var p1 = new Point.origin();
          var p1 = new Point(1,2);
     }
4.在类的构造方法中,调用该类的另一个构造方法
     class Point{
          num x, y;
          Point(this.x,this.y);
          Point.alongXAxis(num x) : this(x, 0);
     }
5.命名构造方法的继承问题
     class Father {
          String name;
          Father.fromJson(Map data){ //父类中没有默认构造方法,只有这一个命名构造方法
               print("这是父类的fromJson方法");
          }
     }
     class Child extends Father{ //子类必须使用这种写法来调用父类的 fromJson方法做初始化
          Child.fromJson(Map data) : super.fromJson(data) {
               print("这是子类的fromJson方法")
          }
     }
6.类的成员方法
     class Rectangle {
          num left, top, width, height;

          //构造方法
          Rectangle(this.left, this.top, this.width, this.height);

          //为 right 和 bottom两个成员变量提供 getter 和 setter 方法
          num get right => left + width;
          set right(num value) => left = value - width;

          num get bottom => top + height;
          set bottom(num value) => top = value - height;
     }
7.抽象类 和 抽象方法
     abstract class Doer { //使用 abstract 修饰的类,就是抽象类
          void doSomething(); //没有方法体的方法 就是抽象方法,抽象方法需要子类去实现
          void greet(){ // 有方法体的方法,是普通的 非抽象方法
               print("hello world!");
          }
     }
     class EffectiveDoer extends Doer {
          void doSomething(){
               print("实现父类的抽象方法,做一些事情")
          }
     }
8.枚举类
     enum Color { red, green, blue}
9.运算符重载
     class Vector {
          num x, y;
          Vector(this.x, this.y);
          Vector operator + (vector v) => new Vector(x + v.x, y + v.y);
          Vector operator - (vector v) => new Vector(x - v.x, y - v.y);
          printVec(){
               print("x: $x, y: $y");
          }
     }
     main(){
          Vector v1 = new Vector(1,2);
          Vector v2 = new Vector(3,4);
          (v1 - v2).printVec(); // -2, -2
          (v1 + v2).printVec(); // 4, 6
     }
10.合并两个类(mixins)
     class A{
          a(){
               print(" 这是 A 的 a 方法");
          }
     }
     class B{
          b(){
               print(" 这是 B 的 b 方法");
          }
     }
     class C = A with B; //使用with 关键字,表示 类C 是由 类A 和 类B 混合而构成的
     main(){
          C c = new C();
          C.a(); // 这是 A 的 a 方法
          C.b(); // 这是 B 的 b 方法
     }
11.静态成员变量和静态成员方法
     class Cons {
          static const name = "张三";
          static sayHello(){
               print("hello, 这是 ${Cons.name}");
          }
     }
     main(){
          Cons.sayHello(); // hello, 这是 张三
          print(Cons.name);//张三
     }

七、泛型

泛型可以减少代码的复杂度,Dart 内置的数据类型List就是一个泛型数据类型,可以往List中塞任何数据类型。

八、导入包和库

库:Libraries, Dart提供了很多功能库,只需要导入对应包即可
1.导入功能包
     import 'dart:html'; 
2.引用其他.dart文件
     使用相对路径引用:./ 或 ../
     util.dart文件:
          int add(int a, int b){
               return a + b;
          }
     demo.dart文件
          import './util.dart' //俩文件在同一目录下
          main(){
               print(add(1,2));
          }
3.为导入的包设置一个别名
     import 'package:lib1/lib1.dart';
     import 'package:lib2/lib2.dart' as lib2; // 使用 as 关键字 为包设置一个别名
     // lib1 包中的 元素
     Element element1 = Element();
     // lib2 包中的元素
     lib2.Element element2 = lib2.Element();
4.导入包中的部分功能
     import 'package:lib1/lib1.dart' show foo; // 只导入lib1包中的 foo
     import 'package:lib1/lib1.dart' hide foo; // 导入除了foo的所有其他部分
5.懒加载导入包
     import 'package:greetings/hello.dart' deferred as hello; // 使用 deferred as 让hello包在使用时才加载

九、异步

异步操作:网络、输入输出、文件选择
如果一个方法中有耗时操作,需要将这个方法设置成 async ,并给其耗时操作加上 await 关键字
async 和 await 是成对出现的; 如果这个方法有返回值,需要将返回值塞到 Future 中并返回
Future<String> getNetData() async {
     http.Response res = await http.get("http://www.baidu.com");

     return res.body;
}
main(){
     getNetData().then((str) { //获取网络数据 并打印出来
          print(str);
     });
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259