Flutter - Dart 基础(关于 var、null、late、const、final 等等)

609 阅读5分钟

我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123…

Dart 简介

  • 关于 Dart

    Dart 是由 Google 提供的开发语言,可在任何平台上开发应用程序。Dart 作为 Flutter 应用程序的编程语言,为驱动应用程序提供了环境,同时,Dart 还支持许多核心的开发任务,例如格式化、分析和测试

  • 相关概念

    • 能够放在变量中的所有内容都是对象,每个对象都是一个类的实例,所有对象都继承于 Object

    • Dart 是强类型语言,但是在声明变量时指定类型是可选的。因为 Dart 可以进行类型推断

    • Dart 语言支持空安全(Null safety)机制。变量在没有声明为可空类时,不能为 null。通常在类型后面加 ?,表示这个类型声明为空

    • Dart 支持泛型。比如 List<int> ,表示一组由 int 类型的对象组成的列表`

    • Dart 支持顶级函数(例如 main 函数)。同时,还支持定于属于类或对象的函数(静态方法 和 实例方法)

    • Dart 支持顶级变量,以及定于属于类或对象的变量(静态变量和实例变量)

    • Dart 没有类似于 Java 那样的 publicprotectedprivate 成员访问限定符。一般以 _ 开头表示私有变量。如 _age


Dart 基础操作

log 输出

Dart 输出日志用 print 方法,语句结尾需要使用分号

print("Hello World")

当打印信息中包含字符串或变量,那么需要用 " " 将整个信息包起来,之后用 ${变量} 获取变量的值

var str = "Hello World!"; 
print('变量str的值是: ${str}'); 

代码注释

Dart 支持单行注释、多行注释和文档注释

  • 单行注释

    // 单行注释
    print("Hello World")
    
  • 多行注释

    ///多行注释
    ///多行注释
    ///多行注释
    print("hello World");
    
  • 文档注释

    /**
    * 文档注释
    * 文档注释
    * 文档注释
    */
    print("hello World");
    

main 函数

很多程序入口都是从 main 函数开始,所以 Dart 也不例外

void main(List<String> args) {
    print("hello World");
}

变量与常量

变量(var、null、late)
  • 使用 var 定义变量

    根据变量的值推断出来变量的类型,类型一旦确定,则不能在改变其类型

    //用 var 定义变量
    var name = "Dart";
    print('name 的类型是: ${name.runtimeType}');  //name 的类型是: String
    
    var age = 10;
    age = "10";                                  //会报错
    print('age 的类型是: ${age.runtimeType}');    //age 的类型是: int
    
  • 使用 var 声明变量

    只是用 var 声明了变量,类型依然可以变化,赋值是什么类型,变量就是什么类型

    //用 var 声明变量
    var age;
    age = 18;
    print('age 类型是:${age.runtimeType}');  //等级类型是:int
    
    age = "18";
    print('age 类型是:${age.runtimeType}');  //等级类型是:String
    
  • 使用明确类型来定义变量

    使用 变量类型 变量名称 = 赋值; 格式

    String name = "Dart";
    print('name 的类型是: ${name.runtimeType}');  //name 的类型是: String
    
    
    int age = 10;
    print('age 的类型是: ${age.runtimeType}');    //age 的类型是: int  
    
  • 默认值 null

    • 使用 ? 修饰这个变量可以为空
    • 没有初始化或者可以空类型的变量都会有一个为 null 的默认值
    var name;
    print('name 的类型是: ${name.runtimeType}');  //name 的类型是: Null
    
    int? age;
    print('age 的类型是: ${age.runtimeType}');  // age 的类型是: Null 
    
  • Dart 没有关键字 publicprotectedprivate,所有用下划线 _ 开头的无论是方法还是变量都是私有的

    String name = "Dart";
    //私有变量
    String _nikeName = "dart";
    
  • 关键字 late

    声明一个初始化不可能为空的变量时,可以使用 late 修饰符。但是在使用变量之前,要确保这个变量必须完成初始化,不然运行时会报错

    late String str;
    void run() {
        str = "使用之前初始化";
        print(str);
    }
    
常量 (const、final)

在 Dart 中,使用 constfinal 声明常量

  • const :编译期就必须确定一个值

  • final :通过计算或函数确定一个值(在运行期间能确定的值)

    void main() {
        // 代码编译时就可以确定 num 的值
        const num = 10000;
        
        // 程序运行起来才可以确定 num1 的值
        final num1 = 3.1415 * num;  
    }
    
  • 使用 const 修饰的构造函数,生成的对象是同一个

    • 使用 final 修饰对象

      void main(List<String> args) {
          final stu1 = Student("dart");
          final stu2 = Student("dart");
          print(identical(stu1, stu2));  // false
      }
      
      class Student {
          String name;
          Student(this.name) {}
      }
      
    • 使用 const 修饰对象 (步骤比较多)

      void main(List<String> args) {
          // const stu1 = Student("dart"); 会报错,因为 const 修饰的对象必须是编译期就确定的对象,而 stu1 是在运行时才能确定的对象 
      }
      
      class Student {
          String name;
          Student(this.name) {}
      }
      

      报错信息

      要么类的构造器方法用 const 修饰,要么从构造函数调用中删除 const 截屏2022-06-05 上午10.24.30.png

      根据提示,改为 const 修饰构造器,依然会报错

      void main(List<String> args) {
          const stu1 = Student("dart");
      }
      
      class Student {
          String name;
          const Student(this.name) {}  // 会报错
      }
      

      报错信息

      如果构造器使用 const 修饰,那么这个类的属性都必须使用 final 修饰

      截屏2022-06-05 上午10.45.43.png

      根据提示,将 Student 中的属性都改为 final 修饰

      void main(List<String> args) {
          const stu1 = Student("dart");
      }
      class Student {
          final String name;
          const Student(this.name) {}
      }
      

      报错信息

      const 修饰的构造函数不能有主体 截屏2022-06-05 上午11.14.37.png

      根据提示,构造函数删除主体部分,程序正常运行。const 修饰的构造函数,传入参数一致,生成的对象是同一个

      void main(List<String> args) {
          const stu1 = Student("dart");
          const stu2 = Student("dart");
          const stu3 = Student("java");
          
          print(identical(stu1, stu2));  //true
          print(identical(stu1, stu3));  //false
      }
      
      
      class Student {
          final String name;
          const Student(this.name); 
      }
      
  • constfinal 修饰表达式

    const a = []; // 使用初始化表达式为常量赋值可以省略掉关键字 const
    final b = const [];
    var c = const [];
    
    print(identical(a, b));  //true
    print(identical(b, c));  //true
    // a、b、c 为同一个对象
    
    
    // 没有使用 final 或 const 修饰的变量可以进行更改
    c = [1, 2, 3];