Flutter开发之Dart语言基础

32次阅读

共计 9685 个字符,预计需要花费 25 分钟才能阅读完成。

Flutter 发展历史

Flutter 是 Google 开发的一款用于帮助开发者在 iOS 和 Android 两个平台构建高质量原生应用的全新移动 UI 框架。说到 Flutter,很多同学可能会将它和下面的几个词关联起来:新兴的、移动端、动态化、跨平台、开发框架。

简单来说,Flutter 是一款移动应用程序 SDK,包含框架、widget 和工具,为开发人员提供了一种在 Android 和 iOS 上构建和部署精美移动应用程序的简单高效的方式。

Flutter 项目由来已久,但真正为人所熟知确是在 2017 年 5 月 Google I/ O 大会上,下面就让我们来看一下 Flutter 项目的发展历程:

  • 2014.10:Flutter 的前身 Sky 在 GitHub 上开源。
  • 2015.10:经过一年的开源,Sky 正式改名为 Flutter,低调期。
  • 2017.5:Google I/ O 正式向外界公布了 Flutter,这个时候 Flutter 才正式进去大家的视野。
  • 2018.6:距 5 月 Google I/O 1 个月的时间,Flutter1.0 预览版。
  • 2018.12:Flutter1.0 发布,它的发布将大家对 Flutter 的学习和研究推到了一个新的起点。
  • 2019.2:Flutter1.2 发布主要增加对 web 的支持。
  • 2019.5:Flutter 1.5 发布,此版本 Flutter 发布了 Web 版本,正式开启了 Flutter 的全平台 UI 框架之路。
  • 2019.7:Flutter 1.7 发布,新增对 AndroidX、Android App Bundles 和 64 位的 Android 应用的支持,加入一些新的功能和 Widget 以及解决一些开发者提出的问题。

随着 Flutter 逐渐走向成熟,其开发生态圈也在不断的发展,学习 Flutter 成为前端开发者不可缺少的傍身技能。

Dart 语言基础

简介

Dart 是由 Google 开发的一门全新的计算机编程语言,后来被 ECMA 批准为标准的计算机编程语言,适用于服务器、浏览器、移动应用和物联网等领域的开发。Dart SDK 由谷歌推出,附带其编译器 – Dart VM。SDK 还包括一个实用程序 – dart2js,一个生成与 Dart 脚本等效的 JavaScript 的转换程序。
总体来说,Dart 是一种面向对象的语言,具有 C 语言风格的语法,可以选择将它编译成 JavaScript。它支持各种编程辅助工具,如:接口,类,集合,泛型和可选类型。
Dart 可以广泛用于创建单页面应用程序。单页应用程序仅适用于网站和 Web 应用程序。单页应用程序可以在网站的不同屏幕之间进行导航,而无需在浏览器中加载不同的网页。

下面是 Dart 与 JavaScript 的一些简单区别:

ps:谷歌发布了一个特殊的 Chromium 版本 – Dart VM。使用 Dartium 可以在浏览器上进行测试之前,不必将代码编译为 JavaScript。

Dart 开发环境

执行 Dart 代码,可以使用两种方式,本地编辑器环境和在线运行环境。

在线运行环境

可以使用 https://dartpad.dartlang.org/ 在线编辑器在线运行代码,如下图所示:

本地编辑器

在本地运行 Dart 代码需要先安装 Dart Sdk,可以从以下地址进行下载:

    • https://dart.dev/tools/sdk/ar…
    • http://www.gekorm.com/dart-wi…

    完成 SDK 安装后,将 Dart 可执行文件添加环境变量,如下所示:

    <dart-sdk-path>\bin

    如果要验证是否成功安装 Dart,可以打开命令提示符并输入以下命令:

    dart

    如果输出相应的信息,即说明安装成功!

    IDE

    目前,支持 Dart 的 IDE 主要有 Eclipse、VSCode、IntelliJ、Android Studio 和 WebStorm。使用 IDE 开发 Dart 应用程序时,只需要安装 Dart 插件即可。例如,下面是 Android Studio 安装 Dart 插件:

    dart2js 工具

    art2js 工具用于将 Dart 代码编译为 JavaScript。将 Dart 代码编译为 JS 可以在不支持 Dart VM 的浏览器上运行 Dart 脚本。
    dart2js 工具作为 Dart SDK 的一部分提供,可以在 /dartsdk/bin 文件夹中找到。要将 Dart 编译为 JavaScript,可以在终端中键入以下命令:

    dart2js - - out = <output_file>.js  <dart_script>.dart

    运行此命令后辉生成一个文件,即与 Dart 代码等效的 JavaScript。

    第一个 Dart 程序

    学习一门新的语言,都会来一个“Hello World!”,学习 Dart 之前,我们也来一个“Hello World!”。

    main() {print("Hello World!"); 
    }

    其中,main()函数是 Dart 中的预定义方法,此方法充当应用程序的入口点。执行上面的代码,输出结果如下:

    Hello World!

    说明 ,JavaScript 没有预定义的入口函数,但在 Dart 程序中,每个 app 都必须有一个顶级的 main() 函数作为应用程序的入口点。

    Dart 基础语法

    代码注释

    注释是提高程序可读性的一种有效方法,注释通常包含代码的作者、函数 / 构造提示等信息。编译器在编译程序时会忽略注释。目前,Dart 支持以下类型的注释:

    // 单行注释
    
    /*
     * 多行注释
     */
    
    /**
     * 文档注释
     */
    
    /// 使用三个斜杠开头
    /// 这是 Dart 特有的文档注释

    Dart 关键字

    关键字在语言的上下文中具有特殊含义,下表是 Dart 语言中的一些关键字:

    说明,和 Java 等面向对象语言一样,如下一些规则对 Dart 也适用:

    空白和换行
    Dart 忽略程序中出现的空格,制表符和换行符。可以在程序中自由使用空格,制表符和换行符,并且可以自由地以简洁一致的方式格式化和缩进程序,使代码易于阅读和理解。

    大小写区分
    Dart 区分大小写,Dart 中大写和小写字符表示不同地含义。

    声明以分号结尾
    每行指令都称为语句。每个 dart 语句必须以分号 (;) 结尾。一行可以包含多个语句。但是,这些语句必须用分号分隔。

    类与对象

    Dart 是一种面向对象的语言,面向对象是一种遵循真实世界建模的软件开发范例。在面向对象的编程世界里,对象可以认为是任何实体的实时表示,具有如下几个特征:

    • 状态:由对象的属性描述。
    • 行为:描述对象的行为方式。
    • 标识:将对象与一组类似此类对象区分开的唯一值。

    而类则是创建对象的蓝图 / 模板,类可以封装对象的数据。

    class TestClass {void display() {print("Dart and Object Orientation"); 
       } 
    }  
    void main() {TestClass c = new TestClass();   
       c.display();}

    内置数据类型

    Dart 支持的内置数据类型主要有以下几种:

    • numbers 数字
    • strings 字符串
    • booleans 布尔
    • lists(也被称之为 arrays)list 和数组
    • sets set 集合
    • maps map 集合
    • runes(用于在字符串中表示 Unicode 字符串)
    • symbols 符号

    其中,没有初始化的变量默认值为 null。数值类型变量的默认值也是 null。数值类型 num 有两个具体子类,分别为 int 和 double,其中 int 为整数值,范围是 -2^53 -2^53 之间;double 则是 64 位的双精度浮点数。

    变量与常量

    变量

    Dart 中定义变量有两种方式,一种是静态类型语言常用的方式,即显式指定变量的类型;另一种则是动态语言的常用方式,不指定类型,由 vm 自动推断。例如:

    // 1. 通过显式指定类型来定义变量
    String name = "张三";
    num age = 18;
    
    // 2. 使用关键字 var,不指定类型
    var address = "深南大道";
    var id = 100;

    需要说明的是,使用 var 定义变量时,即使未显式指定类型,一旦赋值后类型就被固定,如果再改变变量的类型,则会报错:

    var number = 19;
    // 以下代码错误,无法运行,number 变量已确定为 int 类型
    number = "2019";

    对于上面的情况,可以使用动态改变变量的数据类型,即使用 dynamic 或 Object 来定义变量。

    // dynamic 声明变量
    dynamic var1 = "hello";
    var1 = 19;
    print(var1);                 // 19
    
    // Object 声明变量
    Object var2 = 20;
    var2 = "Alice";
    print(var2);              // Alice
    

    常量

    Dart 支持的常量定义方式也有两种,一种是使用 final 关键字,同 Java 中的用法,一个 final 变量只能赋值一次;另一种是 Dart 的方式,使用 const 关键字定义,也是 JavaScript 采用的方式。

    // 使用 final 关键字定义常量
    final height = 10;
    
    // 使用 const 关键字定义常量
    const pi = 3.14;

    需要说明的是,final 定义的常量是 运行时常量 ,而 const 常量则是 编译时常量,也就是说 final 定义常量时,其值可以是一个变量,而 const 定义的常量,其值必须是一个字面常量值。

    final time = new DateTime.now(); // 正确
    const time = new DateTime.now(); // 错误
    
    
    const list = const[1,2,3];       // 正确
    const list = [1,2,3];            // 错误
    

    Dart 基本类型操作

    Dart 支持的基本数据类型主要有以下几种:

    • 数字
    • 字符串
    • 布尔
    • 列表(类似于数组)
    • 集合
    • 映射符文(用于表示字符串中的 Unicode 字符)
    • 符号

    数字

    Dart 中的数字类型有两种类型:整数和双精度类型。

    • 整数:整数值表示非小数值,即没有小数点的数值。例如,10 是整数。
    • 双精度数 :Dart 还支持小数数值,即带小数点的值,Dart 中的 Double 数据类型表示 64 位(双精度) 浮点数。例如,10.10。
    // 整数
    var x = 123;
    var hex = 0xDEADBEEF;
    
    // 双精度数
    var y = 1.199;
    var exponents = 1.42e5;
    

    从 Dart 2.1 开始,必要时整数会自动转换为双精度数,例如:

    double z = 10;  // 相当于 double z = 10.0.

    除此之外,字符串也可以转换为数字,例如:

    // String 转为 int
    var one = int.parse('1');
    assert(one == 1);
    
    // String 转为 double
    var onePointOne = double.parse('1.1');
    assert(onePointOne == 1.1);
    
    // int 转为 String
    String oneAsString = 1.toString();
    assert(oneAsString == '1');
    
    // double 转为 String
    String piAsString = 3.14159.toStringAsFixed(2);
    assert(piAsString == '3.14');

    字符串

    字符串代表一系列字符。例如,如果要存储一些数据,如名称,地址等,则应使用字符串数据类型。Dart 字符串是一系列 UTF-16 代码单元。符文用于表示 UTF-32 代码单元序列。

    Dart 使用关键字 String 来表示字符串文字,字符串的值支持单引号或双引号方式。

    var s1 = 'Single quotes work well for string literals.';
    var s2 = "Double quotes work just as well.";
    

    同事,可以使用 ${expression}将表达式的值放在字符串中。如果表达式是标识符,则可以跳过{}。

    var name = "王五";
    var aStr = "hello,${name}";
    print(aStr);  

    Dart 还支持使用 ”+” 操作符拼接字符串。

    var greet = "hello" + "world";

    使用带有单引号或双引号的三引号创建多行字符串。

    var s1 = '''
    You can create
    multi-line strings like this one.
    ''';

    布尔类型

    和 Java 语言中的 boolean 类型类似,Dart 中的布尔类型仅有 false、true 两个值,不能使用 0、非 0 或者 null、非 null 来表达 false 和 true。

    bool flags;
    print(flags);    // null

    列表

    在 Dart 中,数组是一个 List 对象,大多数人也将它称为列表。Dart 中列表操作与 JavaScript 中的数组相似。

    var list = [1, 2, 3];

    列表使用从 0 开始的索引,其中 0 是第一个元素的索引,list.length- 1 是最后一个元素的索引。可以获得列表的长度并像在 JavaScript 中一样引用列表元素,例如:

    var list = [1, 2, 3];
    assert(list.length == 3);
    assert(list[1] == 2);
    
    list[1] = 1;
    assert(list[1] == 1);

    要创建一个编译时常量的列表,可以在列表文字之前添加 const 关键字,例如:

    var constantList = const [1, 2, 3];

    同事,Dart 在 2.3 版本引入了扩展运算符 (…) 和空值感知扩展运算符 (…?),它提供了一种将多个元素插入集合的简洁方法。例如,使用扩展运算符(…) 将列表的所有元素插入另一个列表:

    var list = [1, 2, 3];
    var list2 = [0, ...list];
    assert(list2.length == 4);

    如果扩展运算符右侧的表达式可能为 null,则可以通过使用支持 null 的扩展运算符 (…?) 来避免异常:

    var list;
    var list2 = [0, ...?list];
    assert(list2.length == 1);

    集合

    Dart 中的 Set 是无序的唯一项的集合,Dart 支持由 Set 文字和 Set 类型提供的集合。例如,下面是一个简单的 Dart 集合:

    var test = {'yiibai.com', 'chlorine', 'bromine', 'iodine', 'astatine'};

    集合支持使用 add()或 addAll()方法,例如:

    var elements = <String>{};
    elements.add('hello');
    elements.addAll(test);

    同样,要创建一个编译时常量的集合,请在 set 文字之前添加 const 关键字:

    final constantSet = const {
      'fluorine',
      'chlorine',
      'bromine',
      'iodine',
      'astatine',
    };

    映射

    映射,又称为关联数组,相当于 Java 中的 HashMap。映射由关联键和值构成,键和值都可以是任何类型的对象。每个键只出现一次,但可以多次使用相同的值。

    var gifts = {
      // Key:    Value
      'first': 'partridge',
      'second': 'turtledoves',
      'fifth': 'golden rings'
    };
    
    var nobleGases = {
      2: 'helium',
      10: 'neon',
      18: 'argon',
    };

    当然,Dart 还可以使用 Map 构造函数创建相同的对象。

    var gifts = Map();
    gifts['first'] = 'partridge';
    gifts['second'] = 'turtledoves';
    gifts['fifth'] = 'golden rings';
    
    var nobleGases = Map();
    nobleGases[2] = 'helium';
    nobleGases[10] = 'neon';
    nobleGases[18] = 'argon';

    要创建一个编译时常量的映射,可以在 map 文字之前添加 const 关键字,例如:

    final constantMap = const {
      2: 'helium',
      10: 'neon',
      18: 'argon',
    };

    符文

    在 Dart 中,符文使用的是字符串的 UTF-32 代码点。Unicode 为世界上所有书写系统中使用的每个字母,数字和符号定义唯一的数值。由于 Dart 字符串是 UTF-16 代码单元的序列,因此在字符串中表示 32 位 Unicode 值需要使用特殊语法。

    在 Dart 中,String 类有几个属性可用于提取符文信息。codeUnitAt 和 codeUnit 属性返回 16 位代码单元。

    符号

    Symbol 对象表示 Dart 程序中声明的运算符或标识符。可能永远不需要使用符号,但它们对于按名称引用标识符的 API 非常有用,因为缩小会更改标识符名称而不会更改标识符符号。

    要获取标识符的符号,请使用符号文字,例如:

    #radix
    #bar

    函数

    函数是一组用于执行特定任务的代码块,我们可以将程序看成是多个函数按照某种逻辑组建的代码块。

    在 Dart 中,函数(或方法)也是一个对象,它的类型是 Function。这意味着,函数可以赋值给变量,也可以当做其他函数的参数。

    基本定义

    在 Dart 中定义函数,基本上与 Java 类似,例如:

    / 定义一个不带返回值的函数,可以带 void, 也可以不带
    void say(var word){print("I say'${word}'";
    }
     
    // 参数可以不用指定类型,如果不指定,则默认是 var
    bool isInt(numVar){return numVar is int;}
     
    // 如果函数只有一个 return 语句可以用 => 简写
    // 需要注意 => 后面只能是一个表达式或者是单条语句。bool isInt2(numVar) => numVar is int;
     
    main(){say('hello world'); // I say 'hello world'
       print(isInt('a')); // false
       print(isInt(1)); // true
    }
    

    参数

    Dart 支持命名可选参数和位置可选参数。其中,命名可选参数使用的是 {}, 位置可选参数使用的是[]。区别就是, 如果用{} 声明,在使用时必须带着参数名,如:a:123;如果用 [] 声明,在使用时需要按照顺序使用。
    命令可选参数

    // 定义一个函数,参数列表用花括号包裹
    enableFlags({bool bold, bool hidden}) {// do something}
    
    // 调用方式,传参时使用 "参数名: 值" 的形式
    enableFlags(hidden:true,bold:false);

    位置可选参数

    // 定义 add 函数
    add(int x, [int y, int z]){
        int result = x;
        if (y !=  null){result = result + y;}
    
        if (z !=  null){result = result + z;}
        print(result);
    }
    
    // 调用
    add(18);           // 18
    add(18,12);        // 30
    add(18, 12, 15);   // 45
    

    如果要给位置可选参数设置默认值,可以使用下面的方式:

    add(int x, [int y=0, int z=0]){print(x +y+z);
    }

    匿名函数

    大部分情况下,函数都有自己的名字,但我们也可以创建没有名字的函数,称为匿名函数。

    var func = (x,y){return x + y;};
    
    print(func(10,11));        // 21

    闭包

    闭包(Closure)是一种能被调用对象,它保存了创建它的作用域的信息,因此闭包可以读取其他作用域内的变量使用。使用匿名函数可以轻松的实现 Dart 的闭包,例如:

    Function makeAdder(num){return (addNum){return addNum + num;};
    }
    main(){var add5 = makeAdder(5);
      var add10 = makeAdder(10);
     
      print(add5(1)); // 6
      print(add10(1)); // 11
    }
    

    运算符

    Dart 语言中的运算符与 Java 中的运算符绝大多数相同,主要的运算符有如下一些:

    • 算术运算符
    • 相等和关系运算符
    • 类型检查运算符
    • 按位运算符
    • 赋值运算符
    • 逻辑运算符

    算术运算符

    Dart 的算术运算符,除了常见的 +、-、*、/、% 之外,Dart 中又多出了一个整除运算符~/,与普通除号的区别是将相除后的结果取整返回。

    assert(2 + 3 == 5);
    assert(2 - 3 == -1);
    assert(2 * 3 == 6);
    assert(5 / 2 == 2.5);
    assert(5 ~/ 2 == 2);
    assert(5 % 2 == 1);

    关系运算符

    关系运算符测试或定义两个实体之间的关系类型。Dart 的关系运算符如下表:

    例如:

    assert(2 == 2);
    assert(2 != 3);
    assert(3 > 2);
    assert(2 < 3);
    assert(3 >= 3);
    assert(2 <= 3);

    类型检查运算符

    类型检查运算符可以方便地在运行时检查类型,Dart 的类型检查运算符主要由 as、is 和 is! 组成。

    按位运算符

    Dart 支持的按位运算符及其作用如下表:

    例如:

    final value = 0x22;
    final bitmask = 0x0f;
    
    assert((value & bitmask) == 0x02);
    assert((value & ~bitmask) == 0x20);
    assert((value | bitmask) == 0x2f);
    assert((value ^ bitmask) == 0x2d);
    assert((value << 4) == 0x220);
    assert((value >> 4) == 0x02);
    

    赋值运算符

    赋值用 = 运算符,如果在前面加上其他运算符(比如 +=)就可以组成复合赋值运算符。Dart 支持的赋值运算符如下表:

    逻辑运算符

    逻辑运算符用于组合两个或多个条件,逻辑运算符返回一个布尔值。

    例如:

    if (!done && (col == 0 || col == 3)) {// ...}

    条件分支

    Dart 中条件表达式和其他语言类似,主要由 if 语句、if…else 语句和 else…if 语句组成。

    例如,if 条件分支

    if(i < 0){print('i < 0');
    }else if(i == 0){print('i = 0');
    } else {print('i > 0');
    }

    switch 条件分支:

    String command = 'OPEN';
    switch (command) {
      case 'CLOSED':
        break;
      case 'OPEN':
        break;
      default:
        print('Default');
    }

    循环语句

    和 Java 的循环语句类似,Dart 的循环语句主要由 for 循环、while 循环和 do…while 循环等循环语句构成。其中,for 循环和 for…in 循环又称为确定 (Definite) 循环,如下表:

    例如:

    for(int i = 0; i < 9; i++) {print(i);
    }

    while 循环和 do…while 循环被称为无限循环,如下表:

    例如:

    / while 循环
    while(true){//do something}
    
    // do-while 循环
    do{//do something} while(true);

    为了控制循环语句,可以使用 break 语句和 continue 语句,如下表:

    例如:
    break 控制语句

    void main() { 
       outerloop: // This is the label name 
    
       for (var i = 0; i < 5; i++) {print("Innerloop: ${i}"); 
          innerloop: 
    
          for (var j = 0; j < 5; j++) {if (j > 3) break ; 
    
             // Quit the innermost loop 
             if (i == 2) break innerloop; 
    
             // Do the same thing 
             if (i == 4) break outerloop; 
    
             // Quit the outer loop 
             print("Innerloop: ${j}"); 
          } 
       } 
    }

    continue 控制语句

    void main() { 
       outerloop: // This is the label name 
    
       for (var i = 0; i < 3; i++) {print("Outerloop:${i}"); 
    
          for (var j = 0; j < 5; j++) {if (j == 3){continue outerloop;} 
             print("Innerloop:${j}"); 
          } 
       } 
    }

    附录:Dart 语言基础教程

    正文完
     0