Dart变量、类型和流程控制

2,236 阅读4分钟

欢迎点赞,转载请注明出处

本节将介绍Dart语言有别于其他编程语言的特性或比较重要的特性。假定,你已经有一些其他编程语言的基础,如C,C++,Java,JavaScript等。
在正式开始之前,有必要介绍下Dart的版本信息,因为Dart的语法规则是跟它的版本有关系的。执行下面的命令:

dart --version

可以看到我本机安装的Dart版本是2.5.0,实际上Dart 2.7.1稳定版已于2020年1月23日发布了。这是因为我们前面介绍过,我们选择安装的Flutter SDK版本是1.9,而不是最新的1.12。

本节及后续有关介绍Dart语法和功能,如与你本机运行的不一致的,请检查下你们的Dart版本号。有兴趣的话,点这里可以看到各个Dart版本之间的更新情况。

变量

我们可以使用以下3种方式声明一个变量:

var name="groupones";
dynamic sex=true;
int age=18;

尽管Dart是强类型语言,但是在声明变量时指定类型是可选的,因为Dart可以进行类型推断。例如,上例的name变量可以推断为是String类型。dynamic表示变量类型是动态,类似于JavaScript语言的var关键字。我们可以通过一个小实验进行验证。

void main() {

  var name="groupones";
  dynamic sex=true;
  int age=18;

  print('sex old value is $sex');
  sex = "男";
  print('sex new value is $sex');
  
}

第7行和第9行print中的$sex表示字符串插值,使用sex变量值替换$sex,这类似于ES6的模板字符串。
我们可以选中文件后,右键选择Run,运行该文件:

可以观察到dynamic变量不同类型值的变化情况:

在Dart中,未初始化的变量拥有一个默认的初始化值:null,它的基类是 Null

final和const都可以定义常量。我们在Hello Widget项目里已经用到过了。

final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);

一个final变量只可以被赋值一次,如果更改final变量值,就会有以下的编译错误弹框:

一个const变量也是常量,是编译时常量。例如:

因为new List()是程序运行阶段才能确定的一个具体值,所以静态编译阶段赋值给const常量会出错,而赋值给final常量则没有问题。那么编译常量有什么用?它可以用于将构造函数声明为const 的,这种类型的构造函数创建的对象是不可改变的,也可以用于定义枚举量。我们将会再后续的部分进行示例介绍。

内置类型

Dart 语言支持下列的类型:

  • 数字类型
    包括int和double类型,基类是 num
  • 字符串类型
    使用 String类表示;
    UTF-16 编码的字符序列。可以使用单引号或者双引号来创建;
    可以使用三个单引号或者三个双引号创建多行字符串;
    可以在字符串中以 ${表达式} 的形式使用表达式,如果表达式是一个标识符,则可以省略掉 {};
    在字符串前加上小写r作为前缀创建 “raw” 字符串,则可以忽略字符串内的需要转义的字符,类似于C#语言的@字符串前缀符号。
  • 布尔类型
    使用bool类表示。
  • 数组类型
    使用List类表示,使用方括号对来创建;
    可以使用扩展操作符(...)将一个 List 中的所有元素插入到另一个 List 中;例如:

    使用 null-aware 扩展操作符(...?)来避免产生异常;下列代码:
var list;
var list2 = [0, ...?list];

等价于

var list;
var list2;
if (list==null){
  list2 = [0];
}else{
  list2 = [0, ...list];
}
  • 集合类型
    使用 Set类表示,使用花括号对来创建;
    集合中的元素是不能重复,考虑下列代码输出是什么:
void main() {
  var listOfInts = [1, 2, 3 , 1, 2, 3];
  var setOfInts = {1, 2, 3 , 1, 2, 3};

  print("listOfInts length is ${listOfInts.length}, setOfInts length is ${setOfInts.length}");
  
}
  • 字典类型 使用Map类 表示,使用花括号对来创建,类似JSON对象;
    Map是用来关联keys和values的对象,每个键只能出现一次但是值可以重复出现多次,例如:
var person = {
  // 键:    值
  'name': 'groupones',
  'sex': true,
  'age': 18
};

流程控制语句

可以使用下面的语句来控制Dart代码的执行流程:

  • if 和 else
  • for 循环
  • while和do-while 循环
  • break和continue
  • switch和case
  • assert 这些流程控制的语法和用法跟其他的编程语言比较类似,下面只介绍下比较重要或特殊一些的用法:

在Dart语言中,for循环中的闭包可以自动遍历对象元素,如下代码:

第6行中的number代表遍历的numbers数组依索引顺序的每一个元素变量。
像List和Set等实现了 Iterable接口的类还支持for-in形式的迭代,上述代码可以改写如下,输出结果是同样的:

void main() {
  var numbers = [1,2,3,4,5];
  for (var number in numbers) {
    print(number);
  }
 }

如果我们想过滤符合某些条件的元素集合,我们可以这样写:

 var numbers = [1,2,3,4,5];
  numbers
  .where((number) => number.isEven)
  .forEach((number) => print(number));

以上代码输出结果为: 2 4

实验三

利用本节知识点及利用相关类方法,编写Dart Command Line App,统计 Flutter计数器(Counter)项目中main.dart整个代码字符串中class和return单词出现的次数,并存储成Map对象。

  • 提示:可以考虑使用String类的split方法和RegExp正则表达式类
  • 挑战1:统计main.dart的代码行数(不包含注释行和空行);
  • 挑战2:统计Dart代码中this关键字出现次数。

上一篇 Hello Dart 下一篇 Dart函数、运算符、异常和类