Dart入门(三)语言特性、库、异步编程

Dart语言——45分钟快速入门(下)

Dart语法学习

语言特性

  • Dart所有的东西都是对象, 即使是数字numbers、函数function、null也都是对象,所有的对象都继承自Object类。

  • Dart动态类型语言, 尽量给变量定义一个类型,会更安全,没有显示定义类型的变量在 debug 模式下会类型会是 dynamic(动态的)。

  • Dart 在 running 之前解析你的所有代码,指定数据类型和编译时的常量,可以提高运行速度。

  • Dart中的类和接口是统一的,类即接口,你可以继承一个类,也可以实现一个类(接口),自然也包含了良好的面向对象和并发编程的支持。

  • Dart 提供了顶级函数(如:main())。

  • Dart 没有 public、private、protected 这些关键字,变量名以"_"开头意味着对它的 lib 是私有的。

  • 没有初始化的变量都会被赋予默认值 null。

  • final的值只能被设定一次。const 是一个编译时的常量,可以通过 const 来创建常量值,var c=const[];,这里 c 还是一个变量,只是被赋值了一个常量值,它还是可以赋其它值。实例变量可以是 final,但不能是 const。

  • 编程语言并不是孤立存在的,Dart也是这样,他由语言规范、虚拟机、类库和工具等组成:

    • SDK:SDK 包含 Dart VM、dart2js、Pub、库和工具。
    • Dartium:内嵌 Dart VM 的 Chromium ,可以在浏览器中直接执行 dart 代码。
    • Dart2js:将 Dart 代码编译为 JavaScript 的工具。
    • Dart Editor:基于 Eclipse 的全功能 IDE,并包含以上所有工具。支持代码补全、代码导航、快速修正、重构、调试等功能。

导入标准库

import 'dart:math';

也可以用相对路径或绝对路径来引用dart文件

import 'lib/student/student.dart';

指定package:前缀,表示导入包管理系统中的库

import 'package:utils/utils.dart';

导入库时,可以使用as关键字来给库起别名,避免命名空间冲突。

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

// 使用lib1中的Element
Element element1 = new Element();
// 使用lib2中的Element
lib2.Element element2 = new lib2.Element(); 

使用showhide关键字控制库中成员的可见性

// 仅导入foo,屏蔽库中其他成员
import 'package:lib1/lib1.dart' show foo;

// 屏蔽foo,库中其他成员都可见
import 'package:lib2/lib2.dart' hide foo;

为了减少 APP 的启动时间,加载很少使用的功能,我们还可以延迟导入库。使用 deferred as关键字延迟导入

import 'package:deferred/hello.dart' deferred as hello;

// 当需要使用时,再通过库标识符调用 loadLibrary函数加载
hello.loadLibrary();

异步编程

Dart与JavaScript一样,是一个单线程模型。但这并不意味着Dart中不能进行异步编程,只是这种异步编程区别于传统的多线程异步方式

Dart中的所有代码都只在一个线程上运行

Dart中的所有代码都只在一个线程上运行,但Dart代码可以运行在多个isolate上。isolate可以看做一个微小的线程,isolate由虚拟机调度,isolate之间没有共享内存,因此它们之间没有竞争,不需要锁,不用担心死锁,因此开销小,性能高。由于没有共享内存,所以它们之间唯一的通信只能通过Port进行,而且Dart中的消息传递也总是异步的。

asyncawait编写代码非常简单,而且编写的代码看起来有点像同步代码,实际上是异步的。

在函数签名中加入async关键字,表示该函数异步执行,await表示等待异步结果执行完成返回Future对象。但有一点需要注意,await只能在async函数中出现,因此往往需要再定义一个async函数,用于包装。上述代码中test函数就是用于包装。

// 导入io库,调用sleep函数
import 'dart:io';

// 模拟耗时操作,调用sleep函数睡眠2秒
doTask() async{
  await sleep(const Duration(seconds:2));
  return "Ok";
}

// 定义一个函数用于包装
test() async {
  var r = await doTask();
  print(r);
}

void main(){
  print("main start");
  test();
  print("main end");
}

补充进程、线程

进程和线程的区别介绍

一道面试题:说说进程和线程的区别

  • 进程是资源分配的最小单位,线程是程序执行的最小单位。

  • 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

  • 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。

  • 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

猜你喜欢

转载自www.cnblogs.com/liyonghua/p/11912037.html