82

Flutter开发之Dart语法基础

 5 years ago
source link: https://www.titanjun.top/2019/02/19/Flutter开发之Dart语法基础/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

QBjMZzR.png!web

  • Dart 是谷歌在 2011 年推出的编程语言,是一种结构化 Web 编程语言,允许用户通过 Chromium 中所整合的虚拟机( Dart VM )直接运行 Dart 语言编写的程序,免去了单独编译的步骤
  • 以后这些程序将从 Dart VM 更快的性能与较低的启动延迟中受益
  • Dart 从设计之初就为配合现代 web 整体运作而考虑,开发团队也同时在持续改进 DartJavaScript 转换的快速编译器
  • Dart VM 以及现代 JavaScript 引擎(V8 等)都是 Dart 语言的首选目标平台
  • Dart 语言和 Swift 语言有很多的相似之处

重要概念

在学习 Dart 语言之前, 先了解一些 Dart 相关的一些概念:

  • O-Objective 中有一切皆对象的说法, 这句话在 Dart 中同样适用
    • 所有能够使用变量引用的都是对象, 每个对象都是一个类的实例
    • Dart 中 甚至连 数字、方法和 null 都是对象
    • 所有的对象都继承于 Object
  • Dart 动态类型语言, 尽量给变量定义一个类型,会更安全,没有显示定义类型的变量在 debug 模式下会类型会是 dynamic (动态的)
  • Dart 会在运行之前解析你的所有代码,指定数据类型和编译时的常量,可以提高运行速度
  • Dart 中的类和接口是统一的,类即接口,你可以继承一个类,也可以实现一个类(接口),自然也包含了良好的面向对象和并发编程的支持
  • Dart 函数
    main()
    
  • 类似的, Dart 支持顶级变量,以及依赖于类或对象(静态变量和实例变量)变量。实例变量有时被称为域或属性
  • Dart 不具备关键字 publicprotectedprivate 。如果一个标识符以下划线 (_) 开始,那么它和它的库都是私有的
  • 标识符可以字母或(_)开始,或者是字符加数字的组合开头

以上只是大概说明了一些 Dart 中的重要概念, 具体的语法使用, 请看下文

基本语法

注释

Dart 的注释分为3种:单行注释、多行注释、文档注释

  • 单行注释以 // 开头
  • 多行注释以 /* 开头,以 */ 结尾
  • 文档注释以 /// 或者 /** 开头

分号;

Dart
Dart

其他语法

Dart
print(Object)

变量和常量

变量

使用 varObjectdynamic 关键字声明变量

var name = 'name';
dynamic name1 = 'name1';
String name2 = 'name2';

// 变量的赋值
name = 'a';
name1 = 'a1';
name2 = 'a2';

未初始化的变量的初始值为 null , 即使是数字也是如此,因为在 Dart 中数字也是一个对象

var name;
dynamic name1;
String name2;

可选类型

在声明变量的时候,你可以选择加上具体的类型:

String name2 = 'name2';

这种方式可以更加清晰的表达你想要定义的变量的类型, 编译器也可以根据该类型为你提供代码补全、提前发现 bug 等功能

注意

对于局部变量,这里遵守 代码风格推荐 部分的建议,使用 var 而不是具体的类型来定义局部变量

常量

  • 常量使用 final 或者 const
  • 一个 final 变量只能赋值一次
  • 一个 const 变量是编译时常量
  • 实例变量可以为 final 但是不能是 const

final

final 修饰的变量(即常量2)

final age = 10;
final int age1 = 20;

// final修饰的变量不能重新赋值, 会报错
age = 20;
age1 = 30;

const

  • const 变量为编译时常量
  • 如果在类中使用 const 定义常量,请定义为 static const
  • 使用 const 定义的常量, 可以直接给定初始值,也可以使用其他 const 变量的值来初始化其值
// const
const m1 = 12;
const double m2 = 23;
const m3 = m1 + m2;

// final修饰的变量不能重新赋值, 会报错
m1 = 10;
m2 = 1.02;

操作符

算术操作符

Dart 支持常用的算术操作符

操作符 解释 + 加号 减号 -expr 负号 * 乘号 / 除号(值为 double 类型) ~/ 除号,但是返回值为整数 % 取模

示例:

assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5);   // 结果是double类型
assert(5 ~/ 2 == 2);    // 结果是integer类型 
assert(5 % 2 == 1);     // 余数

自加自减

Dart 还支持自加自减操作

++var
var++
--var
var--

示例

var a = 0, b = 0;

b = a++;
print('a = $a, b = $b'); //a = 1, b = 0
b = ++a;
print('a = $a, b = $b'); //a = 2, b = 2


b = a--;
print('a = $a, b = $b'); //a = 1, b = 2
b = --a;
print('a = $a, b = $b'); //a = 0, b = 0

关系操作符

运算符 含义 == 等于 != 不等于 > 大于 < 小于 >= 大于等于 <= 小于等于
==
identical()
external bool identical(Object a, Object b);

类型判定操作符

类型判定操作符是在运行时判定对象类型的操作符

操作符 解释 as 类型转换 is 如果对象是指定的类型返回 True is! 如果对象是指定的类型返回 False
  • 只有当 obj 实现了 T 的接口, obj is T 才是 true 。例如 obj is Object 总是 true
  • 使用 as 操作符把对象转换为特定的类型
  • 可以把 as 它当做用 is 判定类型然后调用 所判定对象的函数的缩写形式
if (emp is Person) { // Type check
  emp.firstName = 'Bob';
}

// 上面代码可简化为
(emp as Person).firstName = 'Bob';

注意

如果 empnull 或者不是 Person 类型,则第一个示例使用 is 则不会执行条件里面的代码,而第二个情况使用 as 则会抛出一个异常; 所以在不缺定 emp 是否为空的情况下, 安全起见, 建议使用第一种方式

赋值操作符

= –= /= %= >>= ^= += *= ~/= <<= &=

示例:

// 给 a 变量赋值
a = value;  

// 复合赋值操作符
a += b;  // 等价于a = a + b;

// 如果 b 是 null,则赋值给 b;
// 如果不是 null,则 b 的值保持不变
b ??= value; 
     
// 如下所示:     
  var s;
  print(s);  // null
  print(s ?? 'str');  // str
  s ??= 'string';
  print(s);  // string

逻辑操作符

可以使用逻辑操作符来 操作布尔值:

!expr
||
&&

条件表达式

condition ? expr1 : expr2
// 如果 condition 是 true,执行 expr1 (并返回执行的结果); 否则执行 expr2 并返回其结果

expr1 ?? expr2
// 如果 expr1 是 non-null,返回其值; 否则执行 expr2 并返回其结果

示例:

String toString() => msg ?? super.toString();

// 上面的代码等价于
String toString() => msg == null ? super.toString() : msg;

// 等价于
String toString() {
  if (msg == null) {
    return super.toString();
  } else {
    return msg;
  }
}

级联操作符

级联操作符 ( .. ) 可以在同一个对象上 连续调用多个函数以及访问成员变量。 使用级联操作符可以避免创建 临时变量, 并且写出来的代码看起来 更加流畅

querySelector('#button') // Get an object.
  ..text = 'Confirm'   // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

第一个方法 querySelector() 返回了一个 selector 对象。 后面的级联操作符都是调用这个对象的成员, 并忽略每个操作 所返回的值

// 上面代码等价于
var button = querySelector('#button');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

级联调用也可以嵌套:

final addressBook = (new AddressBookBuilder()
      ..name = 'jenny'
      ..email = '[email protected]'
      ..phone = (new PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

注意

严格来说,两个点的级联语法不是一个操作符, 只是一个 Dart 特殊语法。

流程控制语句

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

  • if-else
  • forfor-in
  • whiledo-while
  • switch
  • assert
  • breakcontinue
  • try-catchthrow

if-else

Dart 支持 if 语句以及可选的 else

if (a == 0) {
  print('a = 0');
} else if (a == 1) {
  print('a = 1');
} else {
  print('a = 2');
}

注意

上述代码中的条件控制语句的结果必须是布尔值

for

可以使用标准的 for 循环, ListSet 等实现了 Iterable 接口的类还支持 for-in 形式的遍历:

var arr = [0, 1, 2];

// for循环
for (var i = 0; i < arr.length; i++) {
  print(arr[i]);
}

// for-in循环
for (var x in arr) {
  print(x);
}

Whiledo-while

// while 循环在执行循环之前先判断条件是否满足:
while (c == 0) {
  print('c = $c');
}

// 而do-while循环是先执行循环代码再判断条件:
do {
  print('c = $c');
} while (c == 0);

Breakcontinue

使用 break 来终止循环:

while (true) {
  if (shutDownRequested()) break;
  processIncomingRequests();
}

使用 continue 来开始下一次循环

for (int i = 0; i < candidates.length; i++) {
  var candidate = candidates[i];
  if (candidate.yearsExperience < 5) {
    continue;
  }
  candidate.interview();
}

Switch

  • Dart 中的 Switch 语句使用 == 比较 integerstring 、或者编译时常量
  • 比较的对象必须都是同一个类的实例, 比较适合枚举值
  • 每个非空的 case 语句都必须有一个 break 语句
  • 另外还可以通过 continuethrow 或者 return 来结束非空 case 语句
  • 当没有 case 语句匹配的时候,可以使用 default 语句来匹配这种默认情况
  • 每个 case 语句可以有局部变量,局部变量只有在这个语句内可见
var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    print('CLOSED');
    break;
  case 'APPROVED':
    print('APPROVED');
    // break;
    // 这里非空的case, 没有break会报错
  case 'DENIED':
    // 这里空的case, 可以不要break
  case 'OPEN':
    print('OPEN');
    continue nowClosed;
//如果你需要实现这种继续到下一个 case 语句中继续执行,则可以 使用 continue 语句跳转到对应的标签(label)处继续执行:
nowClosed:
  case 'PENDING':
    print('PENDING');
    break;
  default:
    print('default');
}

Assert

assert
assert
true
false
// Make sure the variable has a non-null value
assert(text != null);

// Make sure the value is less than 100
assert(number < 100);

// Make sure this is an https URL
assert(urlString.startsWith('https'));

注意

断言只在开发模式下运行有效,如果在生产模式 运行,则断言不会执行

这篇文章的简单介绍就到这里了, 下一篇将会记录 Dart 的基本数据类型


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK