flutter Dart语法

作者: biyu6 | 来源:发表于2019-07-09 14:26 被阅读0次

    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);
         });
    }
    

    相关文章

      网友评论

        本文标题:flutter Dart语法

        本文链接:https://www.haomeiwen.com/subject/kgexkctx.html