Dart入门

01.Dart开发环境安装

概述

  • Dart可以用来开发移动应用、Web应用、开发命令行应用和服务端应用,主要有一下IDE可以选择
  • VS Code 在VS Code中安装Dart插件来开发
  • Android Studio Android Studio主要用来进行移动应用开发
  • WebStorm, IntelliJ, DartPad在线运行(但无法引用三方库)
  • Dart SDK概要
  1. Dart SDK包含开发Web,命令行和服务端应用所需要的库和命令行工具。如果你只是想要开发移动应用,则不需要使用Dart SDK,只需安装 Flutter即可。
  • Dart SDK 安装(需要有homebrew)
  • install
brew tap dart-lang/dart
brew install dart
  • upgrade
brew upgrade dart
  • 检测是否安装成功
dart --version //dart
Dart VM version: 2.7.1 (Thu Jan 23 13:02:26 2020 +0100) on "macos_x64"
  • 设置环境变量
-> vim .bash_profile
-> export PATH=${PATH}:/usr/local/Cellar/dart/2.7.1/bin
-> source .bash_profile
  • VS Code开发环境
  • VS Code下载地址(https://code.visualstudio.com
  • 选组对应操作系统安装包进行安装
  • VS Code配置Dart环境插件(Dart、dart-import)






02.Dart基本概念

重要概念

  • 一切皆对象:所有变量引用的都是对象,数字函数null都是对象,都继承自Object类。
  • Dart 声明变量类型可选:Dart可以进行类型推断,dynamic可以声明一个不确定的类型(与进行类型推断的var不同)。
  • Dart支持泛型:List<int>或List<dynamic>(由任何类型对象组成的列表)
  • Dart支持顶级函数,支持属于类或对象的函数,支持嵌套函数:main
  • Dart支持顶级变量,支持属于类或对象的变量
  • 标识符下划线开头表示库内私有:_number, _name()
  • 标识符由字母、数字、下划线组成,由字母或下划线开头
  • Dart表达式有值,语句没有值
  • Dart工具可以显示警告和错误两个类型

关键字

abstract2 dynamic2 implements2 show1
as2 else import2 static2
assert enum in super
async1 export2 interface2 switch
await3 extends is sync1
break external2 library2 this
case factory2 mixin2 throw
catch false new true
class final null try
const finally on1 typedef2
continue for operator2 var
covariant2 Function2 part2 void
default get2 rethrow while
deferred2 hide1 return with
do if set2 yield3

注:
1. 上下文关键字,只有在特定的场景才有意义
2. 内置标识符,javascript代码转为dart代码更简单
3. dart1.0之后发布的、支持异步的相关标识符

关键字

  • 变量仅存储对象的引用(说明变量也是个对象)
  • 变量声明的时候可以不指定类型
  • 未初始化的变量内容都为null(int未初始化也是null)
  • 可以使用关键字final或者const修饰变量,final只能赋值一次,const为编译时常量,顶层的final变量或者类的final变量在其第一次使用的时候被初始化






03.Dart内置类型

int

  • 长度不超过64位(8字节),具体取值范围依赖于不同的平台。在DartVM上其取值位于-263至263-1之间。编译成JavaScript的Dart使用JavaScript数字,其允许的取值范围在-253至253-1之间
  • 思考:Dart中的int 与 Java中的int和long 如何对应?

double

  • 64位的双精度浮点数字
  • 思考:Dart中的double 与 Java中的double和float 如何对应?

String

  • Dart字符串是UTF-16编码的字符序列。可以使用单引号或者双引号来创建字符串。(无区别)
  • 可以使用 + 运算符将两个字符串连接为一个,也可以将多个字符串挨着放在一起 连接为一个
  • 使用三个单引号或者三个双引号创建多行字符串
  • 字符串前加上 r 作为前缀,创建“raw”字符串(不会被做任何处理)
  • ==运算符判断两个对象内容是否一样

Booleans

  • bool关键字表示布尔类型,布尔类型只有两个对象true和false,编译时常量
  • Dart的类型安全不允许使用类似if(nonbooleanValue)的代码去检查布尔值(if(1),其他语言中非0既是true不成立)

List

  • Dart中数组由List对象表示
  • 下标从0开始
  • List list = List(); //固定长度为数组,无参为可变长度
  • Dart在2.3引入了扩展操作符(...)和null-aware扩展操作符(...?),他们提供了一种将多个元素插入集合的简洁方法,还引入了collection if 和collection for
List list_1 = new List(); //list
List list_2 = List(5); //array

var list = [1, 2, 3];
var list1 = [0, ...list]; //[0, 1, 2, 3];
var list2 = [0, ...?list]; //如果list不为空就赋值

const list3 = [0, 1, 2];
list3[1] = 3; //运行会报错,const的列表不能更改

var list4 = [0, 1, 2, if(2<3)3];//[0, 1, 2, 3]; collection if
var list5 = [1, 2, 3];
var list6 = ["0", for(var i in list5) '$i']; //[0, 1, 2, 3]; collection for

Sets

  • Dart中使用Set类表示无序且元素唯一的集合
  • 支持Set字面量(Dart2.2加入)以及Set类型两种形式的Set
var set1 = {'a'}; //set
var set2 = {}; //!!!不是set
var set3 = <int>{}; //是空set,或者var set3 = <dynamic>{};  
//因为set在dart2.2才加入,之前{}表示map
Set<int> set4 = Set(); //建议标明泛型
set4.add(123);
set4.add(123);//再次add,只有唯一元素

const set5 = {'a'}; //不能再修改

Maps

  • Dart中Map通过Map字面量和Map类型来实现
  • 每个键只能出现一次,但是值的出现没有限制
var map1 = {0:"a", 1:"b"};
Map map2 = Map();
map2[0] = "a";

Map<int, String> map3 = new Map();
map3[0]; //0是key,不是下标,此时为null
map3[0] = "a"; //再取为a

final map4 = const{0:"a", 1:"b"};
map4[1]="aaa"; //运行会报错,不可改变

Runes

  • Dart使用Runes来表示UTF-32编码的字符串
  • String类中codeUnitAt和codeUnit属性返回16位代码单元,runes属性可以获取字符串的Runes

Symbols

  • Symbol表示Dart中声明的操作符或者标识符,改类型的对象几乎不会被使用到
  • 可以使用在标识符前加 # 前缀来获取Symbol
  • Symbol字面量是编译时常量






04.Dart方法

Dart是一种真正面向对象的语言,所以函数也是对象并且类型为Function,这意味着函数可以被复制给变量或者作为其他函数的参数。你也可以像调用函数一样调用Dart类的实例。


参数

  • 函数可以有两种形式的参数:必要参数和可选参数
  • 必要参数定义在参数列表的前面
  • 可选参数则定义在必要参数的后面
可选参数
  • 可选参数分为命名参数位置参数
  • 可在命名参数和位置参数中任选其一使用,但是不能混用
命名参数:
1.使用参数名:参数值 的形式来指定命名参数
2.用大括号来指定命名参数
3.可以提供默认值
4.@required注解来标识一个命名参数是必须的参数

int add(int a, int b, {int c, int d, int e}){
  return a + b;
}

int add({@required int a, @required int b, int c, int d, int e}){ //需要引入包
  return a + b;
}

void main{
 int c = add(2, 3);
 int d = add(2, 3, c:4, e:5);
}
位置参数:
1.使用[]将一些列参数包裹起来作为位置参数
2.可以用 = 为函数的位置参数定义默认值,默认值必须为编译时常量,没有指定默认值的情况下默认值为null

int add(int a, [int b, int c]){
  return a + (b??0) + (c??0);
}

void addValue(int a, [int b=0, int c=0]){
  return a + b + c;
}

void main{
 int a = add(1);
 int b = add(1, 2);
 int c = add(1, 2, 3);
}


main函数

每个Dart程序都必须有一个main()顶级函数作为程序的入口,main()函数返回值为void并且有一个List<String>类型的可选参数


函数作为一级对象

  • 可以将函数作为参数传递给另一个函数
  • 可以将函数赋值给一个变量
void printE(int e){
  print(e);
}
void main(){
//源码
//void forEach(){
//  for (E element in this) f(element);
//}
  var list = [1, 2, 3];
  var f = printE;
  list.forEach(f);
  list.forEach(printE); //void f(E e){}
//相同作用
  for(var v in list){
    printE(v);
  }


  var a = (e) => "xxx $e"; //胖箭头语法
  var b = (String e) => "xxx $e"; 
//相同作用
  var c = (e){
    return "xxx $e";
  }
  var d = (String e){
    return "xxx $e";
  }

  a("mmm");//返回 xxx mmm
}


匿名函数

  • 没有名字的函数就是匿名函数
  • 称之为匿名函数,嚯Lambda表达式嚯Closure闭包
([[类型] 参数[, ...]]){
  函数体
}


词法作用域

  • 变量的作用域在写代码的时候就确定了
  • 大括号内定义的变量只能在大括号内使用(与java类似)


词法闭包

  • 闭包 即一个函数对象,即使函数对象的调用在它原始作用域之外,依然能够访问在它词法作用域内的变量
Function addValue(int baseValue){ //Function可以省略
  return (int j) => baseValue + j; //返回一个词法闭包
}

void main(){
  var add1 = addValue(5);
  print(add1); //打印 Closure:(int) => int ,说明返回的add1是一个闭包

  print(add1(4)); //打印 9,说明5虽然在原始作用域之外了,但是依然能访问
}


函数是否相等

void foo(){} //定义顶层函数

class A {
  static void bar(){} //定义静态方法
  void baz(){} //定义实例方法
}

void main(){
  var x;
  //比较顶层函数是否相等 == 相等
  x = foo;
  assert(foo == x);
  //比较静态方法是否相等 == 相等
  x = A.bar;
  assert(A.bar == x);
  //比较实例方法是否相等:
  var a1 = A(); //A的实例 a1
  var a2 = A(); //A的实例 a2
  var y = a2;
  x = a2.baz;
  //这两个闭包引用了相同的实例对象,因此他们相等
  assert(y.baz == x);
  //这两个闭包引用了不同的实例对象,因此他们不相等
  assert(a1.baz != a2.baz);
}


返回值

  • 所有函数都有返回值
  • 没有显示返回语句的函数最后一行默认执行return null






05.Dart运算符

运算符列表

描述 运算符
一元后缀 表达式++ 表达式-- () [] . ?.
一元前缀 -表达式 !表达式 ~表达式 ++表达式 --表达式
乘除法 * / % ~/
加减法 + -
位运算 << >> >>>
二进制与 &
二进制异或 ^
二进制或 I
关系和类型测试 >= > <= < as is is!
相等判断 == !=
逻辑与 &&
逻辑或 II
空判断 ??
条件表达式 表达式1 ? 表达式2 : 表达式3
级联 ..
赋值 = *= /= += -= &= ^= 等等
优先级:从上到下,从左到右


算数运算符

运算符 描述
+
-
-表达式 一元负,也可以作为反转(反转表达式的符号)
*
/
~/ 除并取整
% 取模
++var var = var+1(表达式值为var+1)
var++ var = var+1(表达式值为var)
--var var = var-1(表达式值为var-1)
var-- var = var-1(表达式值为var)
void main(){
  int a=3, b=2;
  var f = a/b; //得1.5(double) ,在java和c中为取整的1
  print(f);
  var g = a~/b; //得1,这是dart中的除整
  print(g);
}


算数运算符

运算符 描述
== 相等
!= 不等
> 大于
< 小于
>= 大于等于
<= 小于等于


类型判断运算符

运算符 描述
as 类型转换(也用作指定类前缀
is 如果对象是指定类型则返回true
is! 如果对象是指定类型则返回false
class A{
}

class B extends A{
}

void main(){
  A aa = A();
  aa is A; //true
  B bb = B();
  bb is A; //true
  bb as A; //把bb转换为特定类型,要内部会先进行is判断
}


赋值运算符

  • 使用 = 来赋值
  • 使用 ??= 来为值为null的变量赋值
= -= /= %= >>= ^=
+= *= ~/= <<= &= I=
var a = 1;
var b ;
a ??= 2; 
b ??= 4; 
print(a); //打印1   a已赋值, ??=不再为它赋值
print(b); //打印4   b未赋值,??=将它赋值为4


逻辑运算符

运算符 描述
! !表达式 对表达式结果取反
II 逻辑或
&& 逻辑与


按位和移位运算符(仅适用于整数)

运算符 描述
& 按位与
I 按位或
^ 按位异或
~表达式 按位取反
<< 位左移
>> 位右移


条件表达式

  • 主要是用来替代if-else语句
condition ? expr1 : expr2 //同java三目运算符
expr1 ?? expr2 //如果表达式1为非null,则返回其值,否则执行表达式2 并返回其值


级联运算符

  • 级联运算(...)可以让你在同一个对象上连续调用多个对象的变量或方法
class B{
  int a = 4;
  int b = 5;
}
class A{
  int a = 0;
  double b = 1/0;
  String c = "c";
  B temp;
}

void main(){
  A aa = A();
  aa.a = 2;
  aa.b = 2.0;
  aa.c = "asd";

//级联写法
  A bb = A();
  bb..a = 2
  ..b = 1.2
  ..c = "zzz"
  ..temp = B()..a = 3..b = 2;
}


其他运算符

运算符 名字 描述
() 使用方法 代表调用一个方法
[] 访问List 访问List中特定位置的元素
. 访问成员 成员访问符
?. 条件访问成员 与上述成员访问符类似,但是左边的操作对象不能为null,
例如 foo?.bar,如果foo为null则返回null,否则返回bar
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容