美文网首页
flutter系列--Dart语法

flutter系列--Dart语法

作者: 凯玲之恋 | 来源:发表于2019-02-27 11:52 被阅读12次

    1. 重要概念

    1. 能够放在变量中的所有内容都是对象,每个对象都是一个类的实例。甚至于数字、函数和null值都是对象,并且所有对象都继承自Object类。
    2. Dart是强类型语言,但类型标识是可选的,因为Dart可以推断类型。如果要明确说明不需要任何类型,可以使用特殊类型dynamic标识。
    3. Dart支持泛型,如List或List(任何类型的对象列表)。
    4. Dart支持顶级函数(例如main函数),以及绑定到类或对象的函数(分别是静态方法和实例方法)。函数内部也可以创建函数(嵌套函数或本地函数)。
    5. Dart支持顶级变量,以及绑定到类或对象的变量(分别是静态变量和实例变量)。
    6. 与Java不同,Dart没有关键字public、protected和private。如想设置私有变量或函数,则变量和函数名以下划线(_)开头。
    7. 标识符可以以字母或下划线(_)开头,后跟这些字符加数字的任意组合。
    8. Dart有两个表达式(具有运行时值)和语句(不具有)。 例如,条件表达式条件? expr1:expr2的值为expr1或expr2。 将其与if-else语句进行比较,该语句没有任何值。 语句通常包含一个或多个表达式,但表达式不能直接包含语句。
    9. Dart工具可以报告两种问题:警告和错误。警告只是表明您的代码可能无法正常工作,但它们不会阻止您的程序执行。 错误可以是编译时或运行时。 编译时错误会阻止代码执行; 运行时错误导致代码执行时引发异常。
    10. 关键字
      任何语言都有关键字,关键字是在编程时不能使用作为标识符的单词。Dart的关键字如下
    123.png

    编码时应避免使用以上单词作为标识符,如果有必要,可以使用带有上标的单词作为标识符:

    • 带有上标1的单词是上下文关键字,仅在特定位置有含义,它们在任何地方都是有效的;
    • 带有上标2的单词是内置标识符,它们在大多数地方是有效的,但不能用作为类和类型名称或作为一个导入前缀;
    • 带有上标3的单词是与Dart1.0发布后添加的异步支持相关的有限的保留字符,不能在任何标记为async,async * 或sync * 的任何函数体中使用await和yield作为标识符。

    3变量

    3.1 变量的定义

    1.可以使用var来定义变量,变量的类型可以通过变量值推断出来

    var name = "hi"; //String类型
    var age = 18; //int类型
    var high = 1.70; //double类型
    

    如上变量定义后其类型已经确定,不可再将其他类型的值赋给变量
    2.也可以使用特定类型来定义变量

    String name = "bruce"; //String类型
    int age = 18; //int类型
    

    3.如果变量不限于单个类型,则可以使用dynamic或Object来定义变量

    dynamic value = 18;
    print("value = $value");
    value = "bruce";
    print("value = $value");
    value = 3.5;
    print("value = $value");
      
    Object val = 18;
    print("val = $val");
    val = "bruce";
    print("val = $val");
    val = 3.5;
    print("val = $val");
    

    输出结果为

    value = 18
    value = bruce
    value = 3.5
    val = 18
    val = bruce
    val = 3.5
    

    3.2 变量的默认值

    能够放在变量中的所有内容都是对象,所以如果一个变量没有初始化值,那它的默认值就为null

    int value1;
    print("value1 = $value1");
    bool value2;
    print("value2 = $value2");
    var value3;
    print("value3 = $value3");
    dynamic value4;
    print("value4 = $value4");
    

    输出结果为

    value1 = null
    value2 = null
    value3 = null
    value4 = null
    

    3.3 final 和 const

    如果不打算更改变量,可以使用final或者const。一个final变量只能被设置一次,而const变量是编译时常量,定义时必须赋值。

    // Person类
    class Person {
      static const desc = "This is a Person class"; //必须定义时赋值,否则编译时报错
      final name;
      Person(this.name); //对象初始化时赋值一次
    }
    
    // 定义一个Person对象
    Person p = Person("Bruce"); //创建对象时设置一次name
    print("p.name = ${p.name}"); //可正常输出 p.name = Bruce
    p.name = "haha"; //编译器报错
    

    4 内置类型

    Dart语言支持以下类型

    • numbers

    包含int和double两种类型,没有像Java中的float类型,int和double都是num的子类型

    • strings

    Dart的字符串是一系列UTF-16代码单元。创建方法如下:

    String str1 = "hello"; //可以使用单引号或双引号
    print("str1 = $str1");
    String str2 = """Hi,Bruce
    This is Xiaoming.
    """; //使用带有单引号或双引号的三重引号可以创建多行字符串
    print("str2 = $str2");
    

    输出结果为

    str1 = hello
    str2 = Hi,Bruce
      This is Xiaoming.
    
    • booleans

    Dart有一个名为bool的类型,只有两个对象具有bool类型:true和false,他们都是编译时常量。

    • lists

    和其他编程语言常见的集合一样,Dart中使用的集合是数组或有序的对象组。Dart中数组是List对象。

    List arr = ["Bruce", "Nick", "John"];
    print("arr = $arr");
    
    • maps
    Map map = {
    "name": "Bruce",
    "age": 18,
    "high": 1.70
    };
    
    print("map = $map");
    print("map['name'] = ${map['name']}");
    
    var map1 = {
    1: "hi",
    2: "hello",
    3: "yep"
    };
    print("map1 = $map1");
    print("map1[1] = ${map1[1]}");
    

    输出结果为

    map = {name: Bruce, age: 18, high: 1.7}
    map['name'] = Bruce
    map1 = {1: hi, 2: hello, 3: yep}
    map1[1] = hi
    
    • runes

    符文是字符串的UTF-32代码点。在字符串中表示32位Unicode值需要特殊语法,常用方法是 \uXXXX,其中XXXX是4位十六进制值,比如小心心(♥)是\u2665。要指定多于或少于4个十六进制数字,请将值放在大括号中。 比如,微笑(😆)是\u{1f600}。

    String smile = '\u{1f600}';
    print("微笑:$smile");
    
    Runes input = new Runes(
      '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
    print(String.fromCharCodes(input));
    

    输出结果为

    微笑:😀
    ♥  😅  😎  👻  🖖  👍
    

    5 函数

    Dart是一种真正的面向对象语言,因此即使是函数也是对象并且具有类型Function。这意味着函数可以分配给变量或作为参数传递给其他函数。

    5.1 定义方法

    和绝大多数编程语言一样,Dart函数通常的定义方式为

    String getName() {
      return "Bruce";
    }
    

    如果函数体中只包含一个表达式,则可以使用简写语法

    String getName() => "Bruce";
    

    5.2 可选参数

    Dart函数可以设置可选参数,可以使用命名参数也可以使用位置参数

    5.2.1 命名参数

    命名参数,定义格式如 {param1, param2, …}

    // 函数定义
    void showDesc({var name, var age}) {
      if(name != null) {
        print("name = $name");
      }
      if(age != null) {
        print("age = $age");
      }
    }
    
    // 函数调用
    showDesc(name: "Bruce");
    
    // 输出结果
    name = Bruce
    

    5.2.2 位置参数

    位置参数,使用 [] 来标记可选参数。

    // 函数定义
    void showDesc(var name, [var age]) {
      print("name = $name");
      
      if(age != null) {
        print("age = $age");
      }
    }
    
    // 函数调用
    showDesc("Bruce");
    
    // 输出结果
    name = Bruce
    

    5.2.3 默认值

    函数的可选参数也可以使用 = 设置默认值

    // 函数定义
    void showDesc(var name, [var age = 18]) {
      print("name = $name");
      
      if(age != null) {
        print("age = $age");
      }
    }
    
    // 函数调用
    showDesc("Bruce");
    
    // 输出结果
    name = Bruce
    age = 18
    

    5.3 main函数

    和其他编程语言一样,Dart中每个应用程序都必须有一个顶级main()函数,该函数作为应用程序的入口点。

    5.4 函数作为参数

    Dart中的函数可以作为另一个函数的参数。

    // 函数定义
    void println(String name) {
      print("name = $name");
    }
    
    void showDesc(var name, Function log) {
      log(name);
    }
    
    // 函数调用
    showDesc("Bruce", println);
    
    // 输出结果
    name = Bruce
    

    5.5 匿名函数

    // 函数定义
    void showDesc(var name, Function log) {
      log(name);
    }
    
    // 函数调用,匿名函数作为参数
    showDesc("Bruce", (name) {
        print("name = $name");
      });
    
    // 输出结果
    name = Bruce
    

    5.6 嵌套函数

    Dart支持嵌套函数,也就是函数中可以定义函数。

    // 函数定义
    void showDesc(var name) {
      print("That is a nested function!");
      
      //函数中定义函数
      void println(var name) {
        print("name = $name");
      }
      
      println(name);
    }
    
    // 函数调用
    showDesc("Bruce");
    
    // 输出结果
    That is a nested function!
    name = Bruce
    

    6 运算符

    Dart中使用到的运算符如下表格


    Dart中使用到的运算符.png

    6.1 ?.的使用

    //定义类
    class Person {
      var name;
      Person(this.name);
    }
    
    // 调用
    Person p;
    var name = p?.name; //先判断p是否为null,如果是,则name为null;如果否,则返回p.name值
    print("name = $name");
    
    // 输出结果
    name = null
    

    6.2 ~/的使用

    // 代码语句
    var num = 10;
    var result = num ~/ 3; //得出一个小于等于(num/3)的最大整数
    print("result = $result");
    
    // 输出结果
    result = 3
    

    6.3 as的使用,as用来做类型转化

    // 类定义
    class Banana {
      var weight;
      Banana(this.weight);
    }
    
    class Apple {
      var weight;
      Apple(this.weight);
    }
    
    // 调用
    dynamic b = Banana(20);
    (b as Banana).weight = 20; // 正常执行
    print("b.weight = ${(b as Banana).weight}");
    (b as Apple).weight = 30; // 类型转换错误,运行报错
    print("b.weight = ${(b as   Apple).weight}");
    
    //输出结果
    b.weight = 20
    Uncaught exception:
    CastError: Instance of 'Banana': type 'Banana' is not a subtype of type 'Apple'
    

    6.3 is的使用

    // 函数和类代码定义
    getFruit() => Banana(20); // 获取一个水果对象
    
    class Banana {
      var weight;
      Banana(this.weight);
    }
    
    class Apple {
      var color;
      Apple(this.color);
    }
    
    // 调用
    var b = getFruit();
    if(b is Apple) { //判断对象是否为Apple类
      print("The fruit is an apple");
    } else if(b is Banana) { //判断水果是否为Banana类
      print("The fruit is a banana");
    }
    
    // 输出结果
    The fruit is a banana
    

    6.4 ??的使用

    // 操作代码块
    String name;
    String nickName = name ?? "Nick"; //如果name不为null,则nickName值为name的值,否则值为Nick
    print("nickName = $nickName");
      
    name = "Bruce";
    nickName = name ?? "Nick"; //如果name不为null,则nickName值为name的值,否则值为Nick
    print("nickName = $nickName");
      
    // 输出结果
    nickName = Nick
    nickName = Bruce 
    

    6.5 ..的使用,级联操作允许对同一个对象进行一系列操作。

    // 类定义
    class Banana {
      var weight;
      var color;
      Banana(this.weight, this.color);
      
      void showWeight() {
        print("weight = $weight");
      }
      
      void showColor() {
        print("color = $color");
      }
    }
    
    // 调用
    Banana(20, 'yellow')
        ..showWeight()
        ..showColor();
        
    // 输出结果
    weight = 20
    color = yellow
    

    7 控制流语句

    Dart中的控制流语句和其他语言一样,包含以下方式

    • if and else
    • for循环
    • while和do-while循环
    • break和continue
    • switch-case语句

    以上控制流语句和其他编程语言用法一样,switch-case有一个特殊的用法如下,可以使用continue语句和标签来执行指定case语句。

    var fruit = 'apple';
    switch (fruit) {
      case 'banana':
        print("this is a banana");
        continue anotherFruit;
          
      anotherFruit:
      case 'apple':
        print("this is an apple");
        break;
    }
    
    // 输出结果
    this is an apple
    

    8 异常

    Dart的异常捕获也是使用try-catch语法,不过与java等语言稍有不同

    // 定义一个抛出异常的函数
    void handleOperator() => throw Exception("this operator exception!");
    
    // 函数调用
    try {
      handleOperator();
    } on Exception catch(e) {
      print(e);
    } finally { // finally语句可选
      print("finally");
    }
    
    // 输出结果
    Exception: this operator exception!
    finally
    

    9 类

    Dart是一种面向对象的语言,具有类和基于mixin的继承。同Java一样,Dart的所有类也都继承自Object。

    9.1 构造函数

    Dart的构造函数同普通函数一样,可以定义无参和有参,命名参数和位置参数,可选参数和给可选参数设置默认值等。Dart的构造函数有以下几个特点:

    1. 可以定义命名构造函数
    2. 可以在函数体运行之前初始化实例变量
    3. 子类不从父类继承构造函数,定义没有构造函数的子类只有无参无名称的构造函数
    4. 子类定义构造函数时默认继承父类无参构造函数,也可继承指定有参数的构造函数;

    命名构造函数和函数体运行前初始化实例变量

    // 类定义
    class Tree {
      var desc;
      
      // 命名构造函数
      Tree.init() {
        desc = "this is a seed";
      }
      
      // 函数体运行之前初始化实例变量
      Tree(var des) : desc = des;
    }
    
    // 构造函数调用
    Tree t = Tree.init();
    print("${t.desc}");
    
    Tree t1 = Tree("this is a tree");
    print("${t1.desc}");
    
    // 输出结果
    this is a seed
    this is a tree
    

    构造函数继承

    // 类定义
    class Fruit {
      Fruit() {
        print("this is Fruit constructor with no param");
      }
      
      Fruit.desc(var desc) {
        print("$desc in Fruit");
      }
    }
    
    class Apple extends Fruit {
      Apple():super() {
        print("this is Apple constructor with no param");
      }
      
      // 默认继承无参构造函数
      Apple.desc(var desc) {
        print('$desc in Apple');
      }
    }
    
    // 构造函数调用
    Apple();
    Apple.desc("say hello");
      
    // 输出结果
    this is Fruit constructor with no param
    this is Apple constructor with no param
    this is Fruit constructor with no param
    say hello in Apple
    

    9.2 mixin继承

    mixin是一种在多个类层次结构中重用类代码的方法。

    // 类定义
    class LogUtil {
      void log() {
        print("this is a log");
      }
    }
    
    class Fruit {
      Fruit() {
        print("this is Fruit constructor with no param");
      }
    }
    
    class Apple extends Fruit with LogUtil {
      Apple():super() {
        print("this is Apple constructor with no param");
      }
    }
    
    // 调用
    Apple a = Apple();
    a.log(); //可执行从LogUtil继承过来的方法
    
    // 输出结果
    this is Fruit constructor with no param
    this is Apple constructor with no param
    this is a log
    

    10 泛型

    Dart同Java一样,也支持泛型。

    // 类定义
    class Apple {
      var desc;
      Apple(this.desc);
      
      void log() {
        print("${this.desc}");
      }
    }
    
    class Banana {
      var desc;
      Banana(this.desc);
      
      void log() {
        print("${this.desc}");
      }
    }
    
    class FruitFactory<T> {
      T produceFruit(T t) {
        return t;
      }
    }
    
    // 调用
    FruitFactory<Banana> f = FruitFactory<Banana>();
    Banana b = f.produceFruit(Banana("a banana"));
    b.log();
      
    FruitFactory<Apple> f1 = FruitFactory<Apple>();
    Apple a = f1.produceFruit(Apple("an apple"));
    a.log();
      
    // 输出结果
    a banana
    an apple 
    

    参考

    一文了解Dart语法

    相关文章

      网友评论

          本文标题:flutter系列--Dart语法

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