Flutter是Google开发的一款用于帮助开发者在iOS和Android两个平台构建高质量原生应用的全新移动UI框架。说到Flutter,不少同窗可能会将它和下面的几个词关联起来:新兴的、移动端、动态化、跨平台、开发框架。前端
简单来讲,Flutter是一款移动应用程序SDK,包含框架、widget和工具,为开发人员提供了一种在Android和iOS上构建和部署精美移动应用程序的简单高效的方式。web
Flutter项目由来已久,但真正为人所熟知确是在2017年5月Google I/O大会上,下面就让咱们来看一下Flutter项目的发展历程:express
随着Flutter逐渐走向成熟,其开发生态圈也在不断的发展,学习Flutter成为前端开发者不可缺乏的傍身技能。编程
Dart是由Google开发的一门全新的计算机编程语言,后来被ECMA批准为标准的计算机编程语言,适用于服务器、浏览器、移动应用和物联网等领域的开发。 Dart SDK由谷歌推出,附带其编译器 - Dart VM。 SDK还包括一个实用程序 - dart2js,一个生成与Dart脚本等效的JavaScript的转换程序。 整体来讲,Dart是一种面向对象的语言,具备C语言风格的语法,能够选择将它编译成JavaScript。它支持各类编程辅助工具,如:接口,类,集合,泛型和可选类型。 Dart能够普遍用于建立单页面应用程序。单页应用程序仅适用于网站和Web应用程序。单页应用程序能够在网站的不一样屏幕之间进行导航,而无需在浏览器中加载不一样的网页。windows
下面是Dart与JavaScript的一些简单区别: 数组
执行Dart 代码,可使用两种方式,本地编辑器环境和在线运行环境。浏览器
可使用 dartpad.dartlang.org/ 在线编辑器在线运行代码,以下图所示: bash
在本地运行Dart代码须要先安装Dart Sdk,能够从如下地址进行下载:服务器
完成SDK安装后,将Dart可执行文件添加环境变量,以下所示:闭包
<dart-sdk-path>\bin
复制代码
若是要验证是否成功安装Dart,能够打开命令提示符并输入如下命令 :
dart
复制代码
若是输出相应的信息,即说明安装成功!
目前,支持Dart的IDE主要有Eclipse、VSCode、IntelliJ、Android Studio和WebStorm。使用IDE开发Dart应用程序时,只须要安装Dart插件便可。例如,下面是Android Studio安装Dart插件:
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。
学习一门新的语言,都会来一个“Hello World!”,学习Dart 以前,咱们也来一个“Hello World!”。
main() {
print("Hello World!");
}
复制代码
其中,main()函数是Dart中的预约义方法,此方法充当应用程序的入口点。执行上面的代码,输出结果以下:
Hello World!
复制代码
说明,JavaScript没有预约义的入口函数,但在Dart程序中,每一个app都必须有一个顶级的main()函数做为应用程序的入口点。
注释是提升程序可读性的一种有效方法,注释一般包含代码的做者、函数/构造提示等信息。编译器在编译程序时会忽略注释。目前,Dart支持如下类型的注释:
// 单行注释
/*
* 多行注释
*/
/**
* 文档注释
*/
/// 使用三个斜杠开头
/// 这是Dart特有的文档注释
复制代码
关键字在语言的上下文中具备特殊含义,下表是Dart语言中的一些关键字:
空白和换行 Dart忽略程序中出现的空格,制表符和换行符。能够在程序中自由使用空格,制表符和换行符,而且能够自由地以简洁一致的方式格式化和缩进程序,使代码易于阅读和理解。
大小写区分 Dart区分大小写,Dart中大写和小写字符表示不一样地含义。
声明以分号结尾 每行指令都称为语句。每一个dart语句必须以分号(;)结尾。一行能够包含多个语句。可是,这些语句必须用分号分隔。
Dart是一种面向对象的语言,面向对象是一种遵循真实世界建模的软件开发范例。在面向对象的编程世界里, 对象能够认为是任何实体的实时表示,具备以下几个特征:
而类则是建立对象的蓝图/模板,类能够封装对象的数据。
class TestClass {
void display() {
print("Dart and Object Orientation");
}
}
void main() {
TestClass c = new TestClass();
c.display();
}
复制代码
Dart支持的内置数据类型主要有如下几种:
其中,没有初始化的变量默认值为 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中的数字类型有两种类型:整数和双精度类型。
//整数
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(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语句,以下表:
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语言基础教程