一、var 变量、final,const常量

  1. 变量var

变量用关键词var来界说,Dart言语是类型揣度的所以在界说变量的时分能够不必指明变量的类型,比如如下

    void main() {
var namer w 4 , =# c # ( "小明";
var age = 10;
var job;
pro _ C . k G 6 eint(name);
print(age);
print(job);H F 0
}

在上面比Y + q } i * N 1 H如中,界说了变量 name 和 agG N @e ,job,其间给name赋值 “小明”,依据类型揣度name便是String 类型的i 9 0 X h w Y D,给 age赋值 10,依据类型揣度M ? ; g v N k {age 便是 int 类型的。对job没有赋值job变量的默许V K V 1 4值便是null。

需求留意的是变量的类型一旦确G f , , 6 f $ pV s w z g ~ ^ f就不能再给他赋不同类型的值。

  1. 常量final,const

常量用 final 或 const 关键字,比如如下

    void main() {
final a = "好";
const b = 1;
}

需求留意的是,常量在界说的时分必定要进行赋值,且界说好今后不能被修正不然会报错。

二、Dart中的数据类型

在Dart中all is Object ,Dart 中有 numbersV g : S # 4(数值类型),strings (字符串类型),booleans(布尔类型),lX L 2 N | x 9 ( qists(列表类型),maps(字典类型a s p T d u I)等

  1. 数值类型

在Dart中数值类型只要int 和# } c [ double两种,比如如下

   void main() {
int a = 1;
double b = 2;
print(a);
print(b);
}

上面的比如中界说了整数类型的a,和double 类型的 b,打印成果是

flutter: 1

flutter: 2.0

2.String字符串类型

Dart中字符b ^ c f e a / j P串用单引号 ” 或双j o 9 1 D 6 –引号 “” 来创立,比如如下:

  void main() {
var a = "酷爱编O J X程";
var b = '哈哈哈哈';
print(a);
print(b);
}
//输出成果:
//flutter: 酷爱编程
//flutter: 哈哈哈哈

字符串的格局化

在Dart 顶用 ${} 来进行字符串的格局化,比如如下:

  void main() {
var a = "酷爱编) i p K u {程";
var b = '哈哈哈哈';
var c =  "咱们都  ${a + b} ";
print(c);
}
//输出成果为
//flutter: 咱们都  酷爱编程哈哈哈哈

上面的比如中字符串 a 和 b 能够用 + 号 直接拼接在一起

在字符串中能够用反斜杠来进行字符转译

字符串的相关办法运用比如如下:

   void8 K  ` w / 1 main() {
var a = "酷爱编程";
//判别是否为空
pr+ w C 9 k rint(a.isEmpty);
//字符串的长度
print(a.length);
//字符串的类型
print(a.runtimeType);
}
//输出成果为:
//flutter: false
//flutter: 4
//flutter: String

上面比如是字符串, g n的常用办法,isEmpty是判别字符串是否为空,length是求Z K K ` ]字符串的长度,runtimeType是求字符串的类型。` U ; Y Y L U f !

字符串也是一种调集类型,比如如下:

  void main() {
var a = "酷爱编程";
print(a[1]);
}
//输G Z ) Y ` F ~出为:
//flutter: 爱
  1. bool布尔类型

Dart中的布尔类型只要 true和false– 1 E ( w C & ? $H 9 W 4 d B c 比如如下:

 void main() {
var a = false;
print(a.rH + - z J - Su- 7 6 w v : m U 2ntimeType);
}
//N 3 ; u W输出成果^ n f:
//flutter: bool

4.L7 V A pist列t : N表类型(数组类型)

用List来界说列表,能够在&ll . Ut;&g _ & 9 ` + x lgt;内指定列表元素的数据类型,比如如下:

  voi% b z y - ] v } 9d main() {
List? ^ $ & _<int> a = [10,100,1000];
List<String> b = ["热", "爱","编","程"];
}

上面比a N { K如中,尖括号中的类型用来指定元素的数据类型,假如列表指定了元素的数据类型,就只能寄存该种数据类型的数据。假如想在列表中寄存不同类型的数据,能够将列表中元素的类型n s G % T l K用dynamic关键字声明为动态类型的,比如如下:

  void main() {
List<dynamic> a = [10,"哈哈哈",99.9];
}

但是在一C 4 ` :般开发中咱们不需m ; 0 N求指定列表的元素类型,由于Dart是能够类型揣度的,所以直接运用var进行声明即可,上面的比如一般如下声明:

  void mainq i : c() {
var a = [10,"哈哈哈"r T R X 8 B,99.9];
}

列表中的常用办法的运用比如如下:

  void main= C 2 O() {
var a = [10,"哈哈哈",99.9];
//添加元素
a.add("ccc");
//删去一个元素
a.remove(10);
//元素个数
a.length;
//...等等其他办法
}
  1. Map字典类型

字典界说运用比如如下:

  void main() {
Map<String, dynamic> a = {"name": "Flutter" , "langb  7uge": "Datr"};
}

用Map来界说一个字典,在尖括号内来指定字典的key和value的数据类型,需求主要的是和数组相同,一旦类型被确认,那么就必须要和界说的类型一致不然会报错。

由于 Dart是能够类型揣度的,所以上面的比如能够直接用var来界说如下:

void main() {
var a = {"name": "Flutter" , "languge": "Datr"};
print(a);
}
//输} { h ? ( 1 P : r出为:
//flo l  E ] Lutter: {name: Flutter, langug! o @ `e: Datr}

Map能够经过键来获取,设置,新增值,比如如下:

void main() {
var a = {"name": "Flutter" , "languge"| p + * ~: "Dat9 r Y Fr"};
//新增键值对
a["version"] = "1.1.0";
//修正键值
a["name"] = "Swift";
print(a);
}
//输出成果:
//flutter: {name: Swift, languge: Dat= x n @ q or, version: 1G r A o z F 6 h .1.0}

三、Dart中的运算符

1.算数运算符加”+”,减 “-4 . d o ; n !” ,乘”*” ,除”/”,取整 “~/”,取模%

“+”是用来做加的运算,除了数字类型外,字符串,列表,字典也支撑相加运算,比如如下:

    void main() {
var a = 10 + 20;
var b = "10"  + "10";
print(a);
printd ( + 1 +(b);
}
//打印成果:
//flutter: 30
//flutter: 1010

“~/” 是取整的运算符,比如如下:

    void main() {
var a = 15;
var b =  a ~/ 4;
print(b);
}
//打印成果:
//flutter: 3

再其他运算符6 t /与其他编程言语基本相同不做介绍

  1. 比较运算符 == ,!= ,> , <% W x Y D r i . C , >= ,<=

与其他言语基本相同不做介绍

3.类型运算符 as,is, is!

as是b ( 2 V v q做类型的转换

is是判别是否属于某个类型

is!是判别是否不属于n ! Z k ~ : | 0 ^某个J = & 4 K u z类型

比如如下:

    void maiP G 2 4  Z n() {
var dogA = Dog();
var dogB = dogA;
//
ik q Qf (dogB9 P k ` z is Dog ){
dogB.func_swim();
}
//用as来简化上面的代码成果相同
(dogB as Dog).func_swim();
}
//打印成果;
//flutter: 游水
//flutter:o ^ 5 D h M A 游水

上面的比如中 能够3 U h ] . m Y j用as来简化代码。

  1. ??

“??” 是| . l Y ? y G rDart的空条件运算符,便是取默许值的意思,比如如下

    void main() {1 T + E
var a;
var b = a ?? 1;
print(b);
}
//输出成果:
/a d H R y 0 (/flutter5 i o @ J r a * C: 1

上面的比如中, 变量a没有赋值所以默许为null,在将a赋值给b的时分由于aw 1 ~是null,所以 经过?? 给把1赋值给了a。

5.级联运? g + x S l } m算符 “..”

级联运算符能够对某个目标进行接连的操作而不必生成中间变量,比如如下:
比如一` ` w y +

  class Person{
func_one(){
print("Dart言语");
}
func_two(){
print("Flutter运用Dart");
}
}
void mainD [ P 4 % Y C + A() {
Person()..func_o5 $ { ] A h ! }ne()..func_two();
}
//打印成果如下:
//flutter: Dart言语
//flutter: Flutter运用Dart
  1. 点运算符以及“?.”的运用

点运算符用来拜访目标的特点或办法,对不确认是否为null的目标能够用“?.”来进行操作,比如如下:

  class Person{
var name;
}
void main() {
var p =, 0 _ r O Person();
print(p?.name);
}

四、 函数

1.函数的一般书写格局:

回来值  函数称号(参数列表){
函数体
}

比如如下:

  void main() {
int func_add(int a,int b){
return a + b;
}
var c = func_add(1, 2);
print(c);
}
//打印成果:
//flutter: 3

上面比如中main函数是程序的进口, 里边界说了r q I g + 5 ; y Ofunc_add函数

Dart中的all is目标, 所以能够将函数赋值给一个变量或者将函数作为参数,= x h V y E T B Z比如如下;

  void m6 9 p 9 7ai; ^ - (n() {
int func_add(int a,int b){
return a + b;
}
var c = func_add;
var d =: t G l $ B Y c(1,2);
print(d);
}

Dart言语中在界说函数的时分函数的参数类型和回来值类型都能够省掉,Dart言语会依据传入的参数和回来的值来动态揣度。比如如下:/ i 3 ( P |

  void ma$ 9 W ^ W + ? yin() {
func_add(a,b){
re( ` ; ^turn a + b;
}
var c =  func_y [ -add(1, 2);
print(c);
}
//打印成果
//flutter: 3

假如某个函数的函数体只要一句话能够用箭头函数来界说,比如如下:

  void main() {
func_add(a,b) => a + b;
var c =  func_add(1, 2);
print(c);
}q v 8
//输出成果:
//flutter: 3

2.可选参数的函数界说

称号可选参数函数的一般格局为

 回来值类型 函数称号({可选参数列表}){
函数体
}

可选参数放在{}号内部,比如如下:

  void main() {
func_text({a,b}) {
if(a != null){
print(a);
}
if(b} 6 o ) P [ # 3 != null){
print(b);
}
};
func_text(a: 2);5 Y / t F
}
//打印成果
//flutter: 2
上面的比如中界说了函数func_text其间参数 a和b都是可选的,需W X ] y求留意的是,在调用的时分需求参数称号加:的方法来进行传参数

位置可选参数,只需求将可选参数放入中括号即可,比如如下;

  void main() {
func_text(a, [b]) {
if(a != null){
print(a);
}
if(b != null){
print(b);
}
};
func_text(2,3);
}$ o B + {  R ] r
//输出成果
//flutter: 2
//flutt5 y u  & Q } Der: 3

在上面比如中func_tez 5 w I R v z l hxt中有两个参数f H 6 k e L @ K Aa和bf J j r R 5 x / Y,其间b 是可选的。在调用的时分能够不传。

函数可选的能够给个默许值2 6 q,假k @ 5 # c R +如没有默许值函数中取到的参数@ S C值为null,,设置默许值今后假如调用的时分没有传入这个参数,在函数内就会运用默许值,在界说可选参数的时分应该尽量提供一个默许值。

比如如下:

  void ma b t 9 h J * C %in() {
fung Q ) ] pc_text(a, [b = 4]) {
if(a !=u } : E u { null){
print(a);
}
if(b != nup g F o I  vll){
print(b);
}
};
funcU s x ` m Q d C l_text(3);
}
//打印如下:
//flutter: 3
//flutter: 4

3、匿名函数

Dart中没有称号的函数是匿名函数,匿名函数能够直接赋值给变量,经过变量来调用。比如如下:

  void main^ J u P L , 6 C 1() {
var a ={ 1 # (b,c){
return b + c;
};
var d = a(1,2);
prin6  O a 2 ] @ a et{ F ; l(d);
}
//打印如下:
//flutter: 3

在上面的比如中,把匿名函数赋值给了变量a,然后经过a来调用。

五、闭包

闭包是一种特殊的函数。

闭包是界说在函数内部的函数。

闭包能够拜访外部办法内的局部变量并持有。

经典比如如下:

  void maV n C t 9 Ain() {
var  func = a();
func();
func();
fus d m ^ x % R # -nc();
}
a(){
int count = 0;
func_count(){
print(count ++);
}
return func_count;
}
//打印成果:
//flutter: 0
//flutter: 1
//flutter: 2

上面比如中, 函数a中的 func_count函数便是闭包,他界说在a函数内,能够拜访并持有他外部函数的局部变量count,暂时e N l l 3了解到这里后面会详细说明闭包的运用。

六、类

Dart是根据类和承继的面向目标的言语。目标是类的实例。在类中界说了目标的特点和办法。

  1. 自界说类和类的结构G ; $函数

Dart顶用 class关键字来| m 9进行类的界说,比如如下:

class Person {
dou- A Jble weight;
int age;
}

上面的比如中界说了Person类,类中界说了两个特点weight和age;咱们能够经过Person来创立目标,经过类来创立目标需求调用类的结构函数。类的结构函数一般和类的姓名相同。当界说一个类时Dart会默许生成一个没有参数的结构函数,能够直接经过类的称号来调用。比如如下:

    class Person{
var name;
}
void main() {
var p = Person();
print(p?.name);
}

上面的比如中,界说的Person类能够直接经过Person()来创立目标。类目标中的办法特点都能够经过点来拜访调用。

一般DartS _ H ! N q言语的结构办法的书写格局如下:

    class Person{
var name;
var aJ _ 8 & dge;
//一般结构办法的书写格局
Person(this.name,this.age);
}

2.类的实例办法:

类界说了特点和办法,一般特点用来存储数据,办法用来界说行为。

比如如下:

 class Person{
var name;
var age;
//一般结构办法的书c ~ n !写格局
Person(this.name,this.age);
func_run(){
print("在跑步");
}
}

上面的比如中界说了办法func_run()便是Person类中的办L & ( D # d g法。调用的比如如下:

void main() {
var p = Person();
p.func_run();
}

在类顶用this来拜访本身的特点和办法,比如如下:

  class Person{
var name;
var age;
//一般结构办法的书写格局
Person(this.name] 8 9  [ 7,this.age);
func_run(){
print(" ${this.name}  在跑步"); //用this拜访name特点
}
}

类中还有两个比较特殊的办法,Setters 和 Getters办法,Setters用来设置目标的特点,G2 z 8 @etters用来获取目标的特点。在界说特点时Dart会P ` H F 9 s ;默许生成Setters和Getters办法。

  1. 笼统类和笼统办法

Dart中 在笼统类中能够界说笼统办法,笼统办法是只要界说没有函数完成的办法。笼统办法是面向接口开发的基础。

笼统类用abstractn o t v关键字来界说。比如如下:

    abstract class PersonInterfaZ T o L 7 : l B xce{
func_run();
}

上面比如中界说了一个PersonI{ ) r O x 5 b Onterface 的接口,里边只界说了一个func_run()的笼统办法。Person类能够对这个接口进行完成比如如下,用关键词implements来完成一个接口比如如下:

 abstract class PersonInterface{
func_run();
}
class Person impe [ q A s elements PersonInterface{
var name;
var age;
//一般结构办法的书写格局
Person(this.name,thi~ | n B V e l L Es.age);
完成接口函数
func_run(){
print("D W ` 7 ${this.name}  在跑步"); //3  J h ` g I h N用this拜访name特点
}
}

一个类也能够同时完成多个接口。

笼统类不能够被实例化。

  1. 类的承继

子类承继父类,就能够直接运用C M X父类中的特点和办法。而且子类能够重写父类中的特点和办法。DarS J : % R X st顶用extends关键字来进行类的承继。比如如下:

  class Person{
var name;
var age;
//一般结构办法的书写格局
Pej , ; - :rson(this.name,this.age);
func_run(){
print("在跑步");
}
}
class Man extends  Person{
//结构函数调用夫类的结构函数
Man(name,age) : super(name,age);
func_eat(){
pri. ] ) ~ _ 3 dnt("正在吃饭");
}
}

上面的比如中Man类承继继了PerK b cson类,需求留意的是结构函数不能被承继,但能够经过super来调用父类的办法。子类也能够重载父类的办法。比如如下:

  class Person{
var name;
var age;
/D f b 5 h/一般结构办法的书写格局
Person/ S % { D p A(this.n8 = C Uame,this.age);
func_r_ _ H 4un(){
print("在跑步");
}
}
clas6 1 u W t Us Man extends  Person{
//结构函数调用夫类的结构函数
Man(name,age) : super(name,age);
func_eat(){
print("正在吃饭1 : h");
}
@override
func_run(){
print("Man在跑步");
}
}

上面比如中子类C & S ~重载父类的func_run()办法,其间@override关键字用来标示这个办法是子类重载父类的,@override, L @ { r U关键字能够省掉。

  1. 枚举

枚举用enum来界5 ? T说。比如如下:$ C 0 P P

  enum  Language{
Dart,
Oc,
Swift
}
clas= 5 = ms Person{
var name;
Language language;
//一般结构办法的书写格局
Person(this.name,this.language);
}
void main() {
var pB ; 5 & n [ : . ! = Person();
p.languageT X ` r , A = Lanb } # + i Q V Sguage.Dart;
print(p.langu_ ; Hage);
}
//输出:
//Language.Dart

7、 类的Mixin特性

Mixin是Dart中十i [ / {分强壮的一个功用。Dart言语是单承继的只能承继一个父i L n 5类。很多时分需求调集多个类的功用来完成一个复杂的自界说类,这时分Mixin特性就不错。

Mixin的功用便是让一个类把其他类的功用混合进来。比如如下:

 mixin Walker{
func_walk(){
print("跑步");A C @ J : v f - ,
}
}
mi1 A w v : y -xin Swim{W g G E D
func_swim(){
print("游水");
}
}
mixin Flying{
func_flying(){
print("飞");
}
}
class Dog wit7 Z 2 Ih Swim, Wa{ ~ ^ 4 Blker {
}
void main() {
var dog =  Dog();
print(dogQ O T A d s H }.func_wa; q } o d e ? Ulk());
print(dog.func_swim());
}z ! z O

程序运转成果:

//flutter: 跑步

//flutter: 游水

在上面比如中界说了,mixin的跑Walker和游水Swim,然后让Dog类经过with 来恪守。Dog类就有了Walker和Swim里边的功用。

能被用来混合的类是Mix+ E 7 ! A U Pin类,Mixin类不能完成结构办法; A T o H不然不能被其他类混合,用with关键字来进行混合。Mixin也支撑多混合。

  1. 范型

比如如下:

 class Person<T>{
T data;
//一般结构办法的书写格局
Person(tl C 2 e 8 Q [his.data);
}
void main| B c  d ?() {
vau 1 P +r p =Person("xiaoming");
print(p.data);
//打印成果:
//flutter: xiaoming
}

七、Dart异步编程 async , awaitx # l , Future的运用

在Dart言语中能够经过 async , await 关键字来编写异步履行的代码。也能够经过Future相关办法处理异步使命。

  1. asyn~ ` )c 和await关键字的运用

     voiq | 6d main() {
    requestData();
    print("持续履行程序");
    }
    requestData(){
    print("收到数据");
    }
    

调用 上面函数的打印成果是:

flutter: 收到数据

fl. . B ? G & y S 1utter: 持– % / 5 续履行程序

能够看出上面比如中的函数是按顺序履行的。假如咱们模拟真是的网络恳求,那么requestData会有必定的耗时,即应该后打印“收到数据”,先z C | ) } m 2打印“持续履行程序”。这时分; ] F h咱们就需求用到异步处理,对上面的比如修正如下:

    void main() {
requestData();@ a :
print("持续履行v U /程序");
}
req) i ` k o k P y Uuesv p / *tData(i G u |) async {V g X o s H
var data = await "收到的数据";
print(data);
}

上面程序运转成果为:

//flutter: 持续履行程序

//flutter: 收到的数据

现在$ r $ [ b 8 F 3能够看出是先打印了“持续履行程序”,后打印了“收到的数据”。完成了异步的效果。

被异步履行的函数需求用async关键字来润饰,且在函数内需求进行滞后处理的句子要用await关键字来润饰如上面比如中的 requestData()函数用 async关键字润饰, 函数内部 “收到的数据o g b Y T“前用await润饰。

  1. 异步和回调的运用

异步和回调一般都是结合在一起来运用的。如上面的比如中,先从网络恳求中获取数据, 接下来把拿到的数据渲染到UI界面上。便是一个异步回调的运用比如。. 6 ] 8 G C ^ R该比如如下: ? V { G 2

   void main() {
requestData(refreshUI);
print("持续履行程序");
}
rj z ] i f = NefreshUI(data){
print(data);
print("刷新UI界面");
}
requestData(callBack) async {
vah X ! u f F I $r data = await "服务端回来的Json数据";
callBack(data);
}

上面程序P m d ? f : s的运转成果是:

//flutter: 持续履行程序

//flutter: 服务端回来( U U V &的Json数据

//flutter: 刷新UI界面

在Dart中函数能够作为参数,在上面的比如中将refreshUI函数作T T a { L Q为参数传给requestData,在后在req# , i N ! I O : VuestData中拿到数据dk b qata后调用。

  1. FutureN N _ 8 U @ I f 7的运用

$ r T j意一个 async函数都会回来一个Future目标。咱们能够经过FutuQ O 2 S v J F J Sre 的then办法来设置回调。上面的比如能够改写为:

   void main() {
var future =  requestData();
futur} S Te.tT G H 4 t hen( (data){
refreshUI(data);
});
print("持续履行程序");
}
refreshUI(data){
print("刷新UI界面 ${data}");
}a | ! D N 5 S V
requestData() async {
var data = await "服务端回来的JS & Q h n )son数据";, p h T M S S  B
return data;
}

程序运转输出成果:

//flutter: 持续履行程序

//flutter: 刷新UI界面 服务端回来的Json数据

八、模块9 D G 2 m的引用

1.用 import来倒入模块

比如:

在lib 文件夹下创立aa.dart文件,其间aa.dart能够作为模块,在aa.dart中编写如下代码:

void  print_func(){
print("aa文件的函数");
}

在程序的main.dart文件中导入aa.dart文件,就能够调用aa.dart文件中的print_func()函数了,比如如下:

import "./lc @ w w & % _ib.aa.dart";
main(){
print_W  Lfunc();
//打印成果:
//aa文` | + . M D g件的函数
}

import 关键字用来导入模块,也能够选择只导入某个模块的某一部分,比如如下:

在上面比如中的aa.dart 文件中新增一个func_rN 0 0 @un(),func_eat()函数

    void  print_func(){
print("aa文件的函数");
}
void func_run(){
pint("我在跑步");
}
void func_eat(){
print(b  O 0 A } e"在吃饭");
}

在main.dart 顶用关键字shoS ^ Lw只导入aa.dart 中的ry S 7 9 % G Iun_func()部分,假如要导入多个内容,能够运用逗号分割开即可,main– y n B } K 1 ^.dart中的代码如下:

    impi ] W !ort "./lib.aa.dart" show run_func9 O G g j E u = ;
main(){
run_func();
//打印成果:
//我在跑步
}

2.模块E 1 C A | z的重命名

假如在不同的Dart文件中界说了相同称号的函数,将这些文件导入并调用这个函数的时分就会出错,这时分咱们能够用 as关键字来对模块进行重命名的方法防止过错。比如如下:

在lib文件夹下新建一个bb的文件,在里边写如下代码:

 bb.dart文件中写入:
void  print_func(){
print("bb文件的函数");
}
在main.dart中写如下运用:
import "./lib.aa.dart";
import "./lib.bb.dart";
main(){
print_func();
//运转就会报错
}

对于上面的过错能够经过用as关键字对模块重新命名来防止。比如如* # . :下:

在main.dart文件中

    import "./lib.aa.dart";
import "./lib.bb.dart" as bb;
mai^ 9 pn(){
print_func(); //aa.dart中的
bb.print_func(); //bb.dart中的
//打印成果:
//au $ M ` G ! m 6 Ba文件的函数
//bb文件的函数
}

简略的学习笔记

m p 章预告,下一篇写Flutter常用控件的运用以及布局