本文首发于公众号「刘望舒」

关联系列
ReactNative入门系列
React Native组件
Flutter基础系列

前言

Dart是Flutter SDK指定的语言,因此要学习Flutter,Dart是必须掌握的。关于Dart可以写一本书了,这里用一篇文章来介绍下Dart的精髓,带你快速入门。和Java语言类似的部分,这篇文章就尽量不再讲了。

1. Dart开发环境搭建

学习Dart语法最好需要用一个编辑器来实践,这里推荐使用IntelliJ IDEA。先下载Dart SDK,地址为:http://www.gekorm.com/dart-windows/
打开IntelliJ IDEA,菜单中点击File–>Settings–>plugins,在plugins的搜索框中搜索Dart并安装,然后重启IntelliJ IDEA。
点击File–>New Project–>Dart,按照下图配置Dart SDK。

注意要选择第三个选项Constole Application,否则会默认创建一个Web项目。点击Next然后配置项目的名称就可以创建项目了。
在项目中的bin/main.dart中加入如下测试代码:

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

点击菜单的Run–>Run’main.dart’或者点击工具条的运行图标,就能在控制台看到输出的结果:

2. Dart概述

Dart是谷歌开发的计算机编程语言,亮相于2011年10月,最新的版本是Dart2。Dart诞生的原因是谷歌的工程师出于对JavaScript的不满,诞生的初期也赢得了部分前端开发者的青睐。但是这时JavaScript借着NodeJS火了起来,在前端、后端、移动端无孔不入,Dart就渐渐被人遗忘了,可见Dart本身是具有很强的实力的,只是不大走运。谷歌并没有放弃Dart,不遗余力的推广Dart:谷歌的Angular提供了Dart版本,指定Dart为新系统Fuchsia的官方开发语言,Dart为移动UI框架Flutter的开发语言,因此Dart又重新回到了人们的视野中。
Dart通常情况下运行在DartVM上,但是在特定情况下它也可以编译成本地代码运行在硬件上,比如Flutter会将代码编译成指定平台的本地代码来提高性能。

3. Dart特性和重要概念

Dart的特性主要有以下几点:

  1. 执行速度快,Dart是AOT(Ahead Of Time)编译的,可以编译成快速的、可预测的本地代码,这使得Flutter几乎都可以使用Dart来编写。也可以采用JIT(Just In Time)编译。
  2. 易于移植,Dart可编译成ARM和X86代码,这样Dart可以在Android、iOS和其他地方运行。
  3. 容易上手,Dart充分吸收了高级语言特性,如果你已经熟悉C++、C、Java,可以在短短几天内用Dart来开发。
  4. 易于阅读,Dart使Flutter不需要单独的声明式布局语言(XML或JSX),或者单独的可视化界面构建器,这是因为Dart的声明式编程布局易于阅读。
  5. 避免抢占式调度,Dart可以在没有锁的情况下进行对象分配和垃圾回收,和JavaScript一样,Dart避免了抢占式调度和共享内存,因此不需要锁。

Dart的重要概念有以下几点:

  1. 在Dart中,一切都是对象,每个对象都是一个类的实例,所有对象都继承自Object。
  2. Dart在运行前解析所有的代码,指定数据类型和编译时常量,可以使代码运行的更快。
  3. 与Java不同,Dart不具备关键字public、protected、private。如果一个标识符以下划线_开始,那么它和它的库都是私有的。
  4. Dart支持顶级的函数如main(),也支持类或对象的静态和实例方法,还可以在函数内部创建函数。
  5. Dart支持顶级的变量,也支持类或对象的静态变量和实例变量,实例变量有时称为字段或属性。
  6. Dart支持泛型类型,如List<int>(整数列表)或List<dynamic>(任何类型的对象列表)。
  7. Dart工具可以报告两种问题:警告和错误。警告只是说明代码可能无法正常工作,但不会阻止程序执行。错误可以是编译时或运行时的。编译时错误会阻止代码执行; 运行时错误会导致代码执行时报出异常。

4. Dart关键字

关键字
abstract dynamic implements show
as else import static
assert enum in super
async export interface switch
await extends is sync
break external library this
case factory factory factory
catch false new true
class class null try
const finally on typedef
continue for operator var
covariant Function part part
default get rethrow while
deferred hide return with
do if set set

5. 变量

变量声明使用var关键字,未初始化的变量的初始值为null,即便是数字类型的变量也是null。

var name = 'liuwangshu';

name变量的类型被推断为String,也可以显示声明:

String name = 'liuwangshu' ;

如果对象不限于单一类型,可以指定Object或dynamic类型。

Object name = 'liuwangshu' ;

如果定义的变量不会变化,可以使用final或const来代替var,final变量只能设置一次。

final name = 'liuwangshu'
//name = 'zhangwuji' ; //会报错

const变量为编译时常量,如果const变量在类级别,可以使用static const。

const pi = 3.1415926;
const area = pi * 60 * 60;

const不仅仅用来定义常量,也可以使用const来创建常量的值。

var foo = const []; final bar = const []; const baz = [];//相当于`const []`

6. 基本数据类型

Dart的基本数据类型包括Number、String、Boolean、List、Set、Map、 Symbol、Runes。

6.1 Number

number类型为两类:

  • int:整数值不大于64位,具体取决于平台。在Dart VM上,值可以是-2 ^63到2 ^63 - 1,如果编译为JavaScript,允许值为-2^53 to 2^53 - 1。
  • double:64-bit (双精度) 浮点数,符合 IEEE 754 标准。

6.2 String

Dart 字符串是 UTF-16 编码的字符序列。 可以使用单引号或者双引号来创建字符串:

var s1 = '单引号适用于字符串文字';
var s2 = "双引号同样有效";

可以在字符串中使用表达式,用法是: ${expression}。如果表达式是一个标识符,可以省略 {}。

var s = '乾坤大挪移';
assert('张无忌的$s' =='张无忌的乾坤大挪移');

使用三个单引号或者三个双引号可以创建多行字符串对象:

var s1 = '''
第一行
第二行
''';var s2 = """第一行
第二行""";

6.3 Boolean

Dart是强bool类型检查,只有true对象才被认为是true。

var name = '张无忌';
if (name) {print('明教教主');
}

上面的代码编译不能通过,因为name是一个字符串,而不是bool类型。

6.4 List

下面是一个List 的示例:

var list = [1, 2, 3];

List的第一个元素的索引是0,最后一个元素的索引是 list.length - 1 。

var list = [1, 2, 3, 4, 5, 6];
print(list.length);
print(list[list.length-1]);

6.5 Set

Dart中的Set是一组无序的集合。

 var hero = ['张无忌', '风清扬', '张三丰', '独孤求败', '萧峰'];

要创建一个空集,可以在{}前面带有类型参数:

var heros= <String> {};

使用add()或addAll()方法将条目添加到现有集中:

var heros = <String>{};
heros.add('石破天');
heros.addAll(hero);

6.6 Map

Map是一个键值对相关的对象,键和值可以是任何类型的对象,每个键都是唯一的,而一个值则可以出现多次。

var player= {// Keys      Values'20' : '斯诺','3': '艾弗森','40' : '希尔','8' : '麦基','55' : '穆托姆博'
};

使用Map构造函数也可以实现同样的功能:

  var player = new Map();player['20'] = '斯诺';player['3'] = '艾弗森';player['40'] = '希尔';

7. 函数

Dart是一个真正面向对象的语言,函数属于Function对象。这意味着,函数可以赋值给变量,也可以当做其他函数的参数。

 void printName(String name) {print('name is $name');}

7.1 可选参数

可选参数可以是可选位置参数,也可以是可选命名参数,但不能同时使用。

可选命名参数
调用方法的时候,可以使用 paramName: value 的形式来指定参数的名称,这样就可以根据paramName得知参数的含义,提高代码的可读性。

coffeeFlavor (sugar :true ,sugar :false );

定义函数时,使用{param1, param2, …}的形式来指定命名参数:

coffeeFlavor ({bool sugar , bool sugar}) {}

可选位置参数
把函数的参数放到 [] 中就变成可选位置参数了:

String go(String to, [String who]) {var result = 'go to the $to';if (who != null) {result = '$result with $who';}return result;
}

7. 2 默认参数值

可以使用 = 来定义可选参数的默认值, 默认值必须是编译时常量。 如果没有提供默认值,则默认值为 null。

String go(String to, [String who= 'liuwangshu']) {var result = 'go to the $to';if (who != null) {result = '$result with $who';}return result;
}String result= go ('beijing');

7.3 main函数

每个应用都需要有个顶级的main() 函数来作为入口才能执行。 main()函数的返回值为 void 并且有个可选的 List<String> 参数。此前我们举的例子都是在main函数中运行才能得已验证:

void main(){void printName(String name) {print('name is $name');}printName('liuwangshu');
}

7.4 匿名函数

大部分函数都有名字,例如 main() 或者 printElement()。 可以创建没有名字的匿名方法,格式如下所示。

([[Type] param1[, …]]) { codeBlock;
};

下面的代码定义了一个参数为i(该参数没有指定类型)的匿名函数。 list中的每个元素都会调用这个函数打印出来.

  var list = ['张无忌', '风清扬', '张三丰', '独孤求败', '萧峰'];list.forEach((i) {print(list.indexOf(i).toString() + ': ' + i);});

8. 流程控制语句

Dart的流程控制语句如下:

  • if 和 else
  • for循环
  • while和do- while循环
  • break和continue
  • switch和case
  • assert

这些语句的大部分都和Java差不多,这里主要讲解for循环和switch语句。

8.1 for循环

标准的 for 循环:

  var message = new StringBuffer("张无忌");for (var i = 0; i < 3; i++) {message.write('!');}

List和Set等实现了Iterable接口的类还支持for-in形式的遍历:

var hero = ['张无忌', '风清扬', '张三丰', '独孤求败', '萧峰'];
for (var h in hero) {print(h);
}

8.2 switch和case

Dart中Switch语句通过使用 == 来比较整型、字符串或者编译时常量。被比较的对象必须都是同一个类的实例(不能是其子类),并且这个类不允许覆写 ==。另外,枚举类型很适用于在Switch语句使用。

  String today='Friday';switch(today){case 'Monday':print('星期一');break;case 'Friday':print('星期五');break;}

9.捕获异常

捕获异常可以避免异常继续传递。

try {//...
} on OutOfLlamasException {//...
} on Exception catch (e) {print('Unknown exception: $e');
} catch (e) {print('Something really unknown: $e');
}

使用on或者catch来声明捕获语句,也可以同时使用。其中on来指定异常类型,catch来捕获异常对象。
确保某些代码不管有没有出现异常都会执行,可以使用finally语句来实现。

try {//...
} catch(e) {print('Error: $e');
} finally {//...
}

10.为类添加新的功能

Dart是一个面向对象编程语言,支持基于Mixin的继承机制。Mixin可以理解为多继承,在with关键字的后面为一个或者多个类。

class Person{run(){print('跑');}
}class Wushu{use(){print('乾坤大挪移');}
}class Zhangwuji extends Person with Wushu{int age;
Zhangwuji(int age){this.age=age;}
}void main() {var zhangwuji=new Zhangwuji(30);zhangwuji.run();zhangwuji.use();
}

通过如上代码的验证,Zhangwuji类拥有了Person和Wushu这两个类的方法。

11.库的使用

使用import来引入一个库,对于Dart语言内置的库,使用dart: scheme。 对于第三方的库,可以使用文件系统路径或者 package: scheme。

import 'dart:io';
import 'package:mylib/mylib.dart';
import 'package:utils/utils.dart';

指定库前缀
如果导入的两个库具有冲突的名字, 可以使用库的前缀来进行区分。 例如,如果library1和library2 都有一个名字为Element的类,可以这样使用:

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// ...
Element element1 = new Element();           //使用lib1中的Element
lib2.Element element2 = new lib2.Element(); //使用lib2中的Element

导入库的一部分
如果只使用库的一部分功能,则可以选择需要导入的部分内容。其中show代表只导入指定的部分,hide代表除了指定的部分都导入。

// 只导入foo
import 'package:lib1/lib1.dart' show foo;// 除了foo,其他部分都导入
import 'package:lib2/lib2.dart' hide foo;

延迟加载库
延迟加载意味着应用程序可以在需要的时候再加载库,使用延迟加载库的场景主要有以下几点:

  • 减少APP的初始启动时间。
  • 执行A/B测试,例如尝试各种算法的不同实现。
  • 加载很少使用的功能。

要延迟加载一个库,需要先使用 eferred as来导入:

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

当需要使用的时候,调用loadLibrary() 函数来加载库:

greet() async {await hello.loadLibrary();hello.printGreeting();
}

12.异步支持

Dart库中包含许多返回Future或Stream对象的函数。这些函数是异步的,它们在基本操作后会返回,而不等待该操作完成,例如读取一个文件,在打开文件后就返回了。
虽然看起来有点像同步代码,但是async和await的代码是的确异步的。

await readFile()

要使用await,其方法必须带有async关键字:

FileOperate() async {var file= await readFile()
//其他处理
}

13.让类可调用

如果Dart中的类实现了call()函数,那么这个类可以当做方法来调用。

class JointFunction {call(String a, String b, String c, String d) => '$a $b $c $d';
}main() {var jf = new JointFunction();var out = jf("放","手","去","做");//1print('$out');
}

在下面的示例中,JointFunction类定义了一个call()函数,它接收三个字符串并拼接它们。这样在注释1处就可以调用JointFunction类了。

14.创建实例

在Java中创建实例可以用new,在Dart中你可以选择用new,也可以选择不用:

Element element = Element();

对于Android开发来说用new可能更习惯一些,可读性也稍微好点,不用new的话显得更简洁,至于用不用new就看团队的要求和个人的习惯吧,没有绝对的好坏之分。

总结

Dart的知识点有很多,这里只介绍了一部分我认为需要重点掌握的部分,如果想了解更多,可以查看[官方文档][1],关于Dart的学习可以结合Flutter边写边学,不要只抠Dart的细节。
[1]: https://www.dartlang.org/guides/language/language-tour


这里不仅分享大前端、Android、Java等技术,还有程序员成长类文章。

Flutter基础(三)Dart快速入门相关推荐

  1. Redis学习笔记①基础篇_Redis快速入门

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...

  2. 深入理解 Redis Template及4种序列化方式__spring boot整合redis实现RedisTemplate三分钟快速入门

    概述 使用Spring 提供的 Spring Data Redis 操作redis 必然要使用Spring提供的模板类 RedisTemplate, 今天我们好好的看看这个模板类 . RedisTem ...

  3. python编程入门指南-最简单的Python编程入门指南,没基础也能快速入门Python编程...

    原标题:最简单的Python编程入门指南,没基础也能快速入门Python编程 对Python这门编程语言来讲,几乎是没什么不能做到的.最难的不过是如何入门,也就是你进入Python编程的第一步. 其实 ...

  4. Spring Boot 2.x基础教程:快速入门

    点击蓝色"程序猿DD"关注我哟 来源:http://t./ <Star最多的Spring Boot教程继续更新了> 牛皮吹过了! Git仓库和博客专题页也改版完成! 是 ...

  5. spring cloud入门_Spring Boot 2.x基础教程:快速入门

    简介 在您第1次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复黏贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot ...

  6. 总觉得该分享点什么!零基础小白如何快速入门前端?

    1.首先零基础学习前端先要有一个计划,了解前端要学习哪些技术. 2.做好自己的时间规划,如何快速入门前端那肯定是需要不断的提高自己的学习效率,学习过程总尽量把手机调至静音给自己一个安静的学习环境和氛围 ...

  7. 【MATLAB Image Processing Toolbox 入门教程三】快速入门之“在多光谱图像中寻找植被”

    [MATLAB Image Processing Toolbox 入门教程三] 本篇摘要 一.从多光谱图像文件导入彩色红外通道 二.构建近红外光谱散射图 三.计算植被系数并显示其定位 四.综合实例部分 ...

  8. Spring Boot 2.x 基础教程: 快速入门

    一.SpringBoot介绍 1.1 SpringBoot简介 SpringBoot是由Pivotal团队研发的,SpringBoot并不是一门新技术,只是将之前常用的Spring,SpringMVC ...

  9. qimage 像素 替换颜色_像素画基础规则新手快速入门教程

    像素画毫无疑问是一门技术,大部分技术都有规则.程序员学新的编程语言,首先要看新语言的官方文档,了解语法和案例,学像素画是不是也可以这样呢? 那么像素画的规则是什么呢? 像素画产生于计算机性能很差的早期 ...

最新文章

  1. sql参数化还是被注入了_面试官问你 SQL 注入攻击了吗?
  2. SQL之inner join/left join/right join
  3. 四川省内二本计算机公立好的大学排名,四川有哪些二本院校是公立的?附四川省公立二本大学排名及分数线...
  4. 【LeetCode笔记】48. 旋转图像(Java、矩阵、偏数学、原地算法)
  5. linux下使用ThinkPHP注意大小写问题
  6. (23)FPGA面试技能提升篇(SSC接口、V35接口)
  7. java获取数据库当前时间_java中获取系统的当前时间
  8. linux 用vi命令的使用以及vi编辑后的后续保存退出等相关命令的使用
  9. Fiddler详解-Fiddler Classic
  10. flex java blazeds_使用BlazeDS实现Java和Flex通信(转载)
  11. 前后端分离,vue+springboot导出dbf
  12. Android音视频开发;斗鱼直播实现
  13. u-boot下载地址
  14. C语言之memcpy()函数
  15. android 视频相册,安卓11版本保存视频到相册,提示保存成功,相册里没有视频...
  16. Python做数据处理(二):贷款风险预测
  17. 如何计算TCP吞吐量
  18. 简单理解Callable接口
  19. 蓝牙APP开发你应该知道的几件事
  20. 机房环境监控的系统概述

热门文章

  1. Flask werkzeug.exceptions.BadRequest: 400 Bad Request: Failed to decode JSON object: None
  2. mysql 中的expr_MYSQL IF 和 IFNULL 函数 IF(expr1,expr2,expr3) IFNULL(expr1,expr2)
  3. sharepoint 2019 安装
  4. LiteOS内核教程01 | IoT-Studio介绍及安装
  5. 2020 shodan 配置详解
  6. 使用flask框架写挡板
  7. 解读JAVAEE是什么样的Java
  8. java语法基础 - 第五部分
  9. 华三、华为和思科的Option 43属性的对比
  10. 从有道笔记再谈个人知识管理系统的功能设置