本笔记整理自大地老师的 Dart 笔记,同时加入了自己写的一些测试例子。
环境搭建 要在我们本地开发 Dart 程序的话首先需要安装 Dart SDK
官方文档:https://dart.dev/get-dart
1 2 3 4 5 6 7 8 9 10 11 windows(推荐): http: mac: 如果 mac 电脑没有安装 brew 这个工具首先第一步需要安装它: https: brew tap dart-lang/dart brew install dart
开发工具 1 2 3 4 5 6 7 Dart 的开发工具有很多: IntelliJ IDEA 、 WebStorm、 Atom、Vscode 等 这里我们主要给大家讲解的是如果在 vscode 中配置 Dart。 1 、找到 vscode 插件安装 Dart2 、找到 vscode 插件安装 code runner, Code Runner 可以运行我们的文件
变量 Dart 中定义变量可以使用具体的类型(int、double、String、bool 等)申明 ,也可以通过 var 关键字来申明变量。
常量
final 和 const 修饰符都可以表示常量。
const 值不变,一开始就得赋值。
final 可以开始不赋值,只能赋一次。而 final 不仅有 const 的编译时常量的特性,最重要的它是运行时常量,并且 final 是惰性初始化,即在运行时第一次使用前才初始化。
注意:永远不改变的量,请使用 final 或 const 修饰它,而不是使用 var 或其他变量类型。1 2 3 4 5 6 7 8 9 10 11 12 13 14 main() { const PI = 3.14159 ; print (PI); final a = 1 ; print (a); final time = new DateTime .now(); print (time); }
常用数据类型 Dart 中支持以下常用数据类型:
1 2 3 4 5 6 7 8 9 10 11 Numbers(数值) int double Strings(字符串) String Booleans(布尔) bool List (数组) 在 Dart 中,数组是列表对象,所以大多数人只是称它们为列表 Maps(字典) 通常来说,Map 是一个键值对相关的对象。键和值可以是任何类型的对象。每个键只出现一次,而一个值则可以出现多次
基本使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 main() { var str1 = "Hello" ; String str2 = "World" ; print ("$str1 $str2 " ); print (str1 + " " + str2); var str3 = '''Hello World''' ; print (str3); int x = 1 ; x = 20 ; print (x); double d = 99.9 ; d = 100 ; print (d); bool flag = true ; if (flag) { print ('真' ); } else { print ('假' ); } var list1 = ['a' , 'b' , 'c' ]; print (list1); var list2 = new List (); list2.add('a' ); list2.add('b' ); list2.add('c' ); print (list2); var list3 = new List <String >(); list3.add("Hello" ); print (list3); var person1 = { "name" : "张三" , "age" : 20 , "work" : ["程序员" , "送外卖" ] }; print (person1); print (person1["name" ]); print (person1["work" ]); var person2 = new Map (); person2["name" ] = "李四" ; person2["age" ] = 21 ; person2["work" ] = ["程序员" , "送外卖" ]; print (person2); }
使用 is
关键词来判断类型
1 2 3 4 5 6 7 8 9 10 main() { var x = 123 ; if (x is String ) { print ('是 String 类型' ); } else if (x is int ) { print ('是 int 类型' ); } else { print ('是其他类型' ); } }
运算符 Dart 运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 算术运算符 + - * / ~/ (取整) %(取余) 关系运算符 == != > < >= <= 逻辑运算符 ! && || 赋值运算符 基础赋值运算符 = ??= 复合赋值运算符 += -= *= /= %= ~/=
基本使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 main() { var x = 10 ; var y = 3 ; print (x / y); print (x ~/ y); print (x % y); var a = 123 ; var b = 123 ; var c = "123" ; var d = 123.0 ; if (a == b) { print ('a 等于 b' ); } if (a == c) { print ('a 等于 c' ); } if (a == d) { print ('a 等于 d' ); } bool flag = false ; print (!flag); int aa = 10 ; int bb; aa ??= 100 ; bb ??= 200 ; print (aa); print (bb); / int xx = 10 ; xx += 10 ; print (xx); }
条件表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 main() { bool flag = true ; if (flag) { print ("true" ); } else { print ("false" ); } String sex = "女" ; switch (sex) { case "男" : print ("男" ); break ; case "女" : print ("女" ); break ; default : print ("不男不女" ); break ; } String s = flag ? "我是 true" : "我是 false" ; print (s); var a = 20 ; var b = a ?? 30 ; print (b); }
类型转换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 main() { int num = 20 ; double d = 30.0 ; String str = "50" ; print (num .toString()); print (d.toString()); print (int .parse(str)); print (double .parse(str)); print (int .tryParse("100a" )); try { var myNum = double .parse("" ); print (myNum); } catch (err) { print (err); } var myStr = '' ; if (myStr.isEmpty) { print ('myStr 为空' ); } else { print ('myStr 不为空' ); } var myStr2; if (myStr2 == null ) { print ('myStr2 为空' ); } else { print ('myStr2 不为空' ); } var x = 0 / 0 ; print (x); if (x.isNaN) { print ("x is NaN" ); } }
循环语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 main() { var a = 10 ; var b = a--; print (a); print (b); var aa = 100 ; var bb = --aa; print (aa); print (bb); var list = ['新闻0' , '新闻1' , '新闻2' , '新闻3' , '新闻4' ]; for (var i = 0 ; i < list.length; i++) { if (i % 2 == 0 ) { print (list[i]); } } var i = 1 ; var sum = 0 ; while (i <= 100 ) { sum += i; i++; } print (sum); i = 1 ; sum = 0 ; do { sum += i; i++; } while (i <= 100 ); print (sum); sum = 0 ; for (var i = 0 ; i < 5 ; i++) { if (i > 3 ) { break ; } sum += i; } print (sum); sum = 0 ; for (var i = 0 ; i < 5 ; i++) { if (i % 2 == 0 ) { continue ; } sum += i; } print (sum); }
集合类型 List 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 main() { List myList = ['AA' , 'BB' , 'CC' ]; myList.add('DD' ); var newList = myList.reversed.toList(); print (newList); var str = myList.join('-' ); print (str); }
Set 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 main() { var set = new Set (); set .add('AA' ); set .add('BB' ); set .add('AA' ); print (set ); print (set .toList()); var myList = ['AA' , 'BB' , 'AA' , 'CC' , 'AA' , 'BB' ]; var mySet = new Set (); mySet.addAll(myList); print (mySet); print (mySet.toList()); }
Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 main() { Map zhangSan = {"name" : "张三" , "age" : 20 }; var liSi = new Map (); liSi["name" ] = "李四" ; liSi["age" ] = 21 ; print (zhangSan.keys.toList()); print (zhangSan.values.toList()); zhangSan.addAll({ "sex" : "男" , "work" : ['敲代码' , '送外卖' ] }); print (zhangSan); zhangSan.remove("sex" ); print (zhangSan); }
集合的 forEach、map、where、any、every 方法使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 main() { var list = ['AA' , 'BB' , 'CC' ]; for (var i = 0 ; i < list.length; i++) { print (list[i]); } for (var item in list) { print (item); } list.forEach((element) { print (element); }); var myList = [1 , 3 , 4 ]; var newList = myList.map((e) { return e * 2 ; }); print (newList.toList()); var newList2 = myList.where((element) { return element > 1 ; }); print (newList2.toList()); var f = myList.any((element) { return element > 3 ; }); print (f); var g = myList.every((element) { return element > 1 ; }); print (g); var set = new Set (); set .addAll(['1' , '2' , '3' ]); set .forEach((element) => print (element)); var zhangSan = {"name" : "张三" , "age" : 20 }; zhangSan.forEach((key, value) { print ("$key ---$value " ); }); }
函数 函数定义、作用域 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 main() { printInfo("Hello World" ); int sum = getSum(1 , 2 ); print (sum); void exec() { void sayHello() { print ("Hello" ); } sayHello(); } exec(); } void printInfo(String info) { print (info); } int getSum(int a, int b) { return a + b; }
函数传参、默认参数、可选参数、命名参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 main() { var sum = getSum(10 ); print (sum); printUserInfo("张三" , 20 ); printUserInfo("李四" ); printUserInfo2("张三" , "女" , 20 ); printUserInfo2("李四" ); printUserInfo3("王五" , sex: "未知" , age: 22 ); fun2(fun1); } int getSum(int n) { var sum = 0 ; for (var i = 1 ; i <= n; i++) { sum += i; } return sum; } void printUserInfo(String name, [int age]) { if (age == null ) { print ("姓名:$name ---年龄保密" ); } else { print ("姓名:$name ---年龄:$age " ); } } void printUserInfo2(String name, [String sex = '男' , int age]) { if (age == null ) { print ("姓名:$name ---性别:$sex ---年龄保密" ); } else { print ("姓名:$name ---性别:$sex ---年龄:$age " ); } } void printUserInfo3(String name, {String sex = '男' , int age}) { if (age == null ) { print ("姓名:$name ---性别:$sex ---年龄保密" ); } else { print ("姓名:$name ---性别:$sex ---年龄:$age " ); } } fun1() { print ("fun1" ); } fun2(fn) { fn(); }
箭头函数、匿名函数、自执行方法、方法递归 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 main() { List myList = [1 , 3 , 4 ]; myList.forEach((element) => print (element)); var newList = myList.map((e) => e > 2 ? e * 2 : e); print (newList.toList()); var myNum = () { return 10 ; }; print (myNum()); ((int n) { print ("我是自执行方法" ); print (n * 10 ); })(18 ); var sum = fn(100 ); print (sum); } int fn(int n) { if (n == 1 ) { return 1 ; } return n + fn(n - 1 ); }
闭包 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 main() { var f = fn(); f(); f(); f(); } fn() { var x = 1 ; return () { x++; print (x); }; }
类与对象 面向对象的介绍 面向对象编程(OOP)的三个基本特征是:封装、继承、多态
封装 :封装是对象和类概念的主要特性。封装,把客观事物封装成抽象的类,并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。
继承 :面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
多态 :允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。
Dart 所有的东西都是对象,所有的对象都继承自 Object 类。
Dart 是一门使用类和单继承 的面向对象语言,所有的对象都是类的实例,并且所有的类都是 Object 的子类
一个类通常由属性和方法组成。
Dart 和其他面向对象语言不一样,Dart 中没有 public、private、protected 这些访问修饰符,但是我们可以使用 _
把一个属性或者方法定义成私有。
类与对象的基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Person { String _name; int age; Person(this ._name, this .age); Person.now() { print ('我是命名构造函数' ); } Person.setInfo(String name, int age) { this ._name = name; this .age = age; } void printInfo() { print ("${this ._name} ---${this .age} " ); } void _sayHello() { print ("_sayHello 是一个私有方法" ); } execRun() { this ._sayHello(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Rect { int width; int height; Rect(this .width, this .height); getArea() { return this .width * this .height; } get area { return this .width * this .height; } set areaHeight(height) { this .height = height; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import 'Person.dart' ;import 'Rect.dart' ;main() { Person p = new Person("张三" , 20 ); p.printInfo(); p.execRun(); Person p2 = Person.now(); Person p3 = Person.setInfo("李四" , 21 ); p3.printInfo(); var r = Rect(10 , 5 ); print (r.getArea()); print (r.area); r.areaHeight = 10 ; print (r.area); }
类中的初始化列表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Rect { int width; int height; Rect() : width = 3 , height = 2 { print ("${this .width} ---${this .height} " ); } get area { return this .width * this .height; } }
1 2 3 4 5 6 import 'Rect.dart' ;main() { var r = Rect(); print (r.area); }
类的静态变量与静态函数 Dart 中的静态成员:
1、使用 static 关键字来实现类级别的变量和函数;
2、静态方法不能访问非静态成员,非静态方法可以访问静态成员;
1 2 3 4 5 6 class Person { static String name = '张三' ; static void showName() { print (name); } }
1 2 3 4 5 6 import 'Person.dart' ;main() { print (Person.name); Person.showName(); }
对象操作符 Dart 中的对象操作符:
?
条件运算符
as
类型转换
is
类型判断
..
级联操作(连缀)
1 2 3 4 5 6 7 8 9 class Person { String name; num age; Person(this .name, this .age); void printInfo() { print ("${this .name} ---${this .age} " ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import 'Person.dart' ;main() { Person p = Person("张三" , 20 ); p?.printInfo(); Person p2; p2?.printInfo(); if (p is Person) { p.name = '李四' ; } p.printInfo(); print (p is Object ); var p3; p3 = '' ; p3 = new Person("王五" , 22 ); p3.printInfo(); (p3 as Person).printInfo(); Person p4 = new Person("AA" , 10 ); p4.printInfo(); p4 ..name = "BB" ..age = 11 ..printInfo(); }
类的继承
面向对象的三大特性:封装 、继承、多态
Dart 中的类的继承:
子类使用 extends 关键词来继承父类;
子类会继承父类里面可见的属性和方法,但是不会继承构造函数;
子类能复写父类的方法;
1 2 3 4 5 6 7 8 9 10 class Person { String name; num age; Person(this .name, this .age); Person.xxx(this .name, this .age); void printInfo() { print ("${this .name} ---${this .age} " ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import 'Person.dart' ;class Teacher extends Person { String sex; Teacher(String name, num age, String sex) : super (name, age) { this .sex = sex; } @override void printInfo() { print ("${this .name} ---${this .age} ---${this .sex} " ); } run() { print ("${this .name} ***${this .age} ***${this .sex} " ); } }
1 2 3 4 5 6 7 import 'Teacher.dart' ;main() { Teacher t = new Teacher('张三' , 20 , '男' ); t.printInfo(); t.run(); }
抽象类 Dart 抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
抽象类通过 abstract 关键字来定义;
抽象方法不能用 abstract 声明,Dart 中没有方法体的方法我们称为抽象方法;
如果子类继承抽象类必须得实现里面的抽象方法;
如果把抽象类当做接口实现的话,必须得实现抽象类里面定义的所有属性和方法;
抽象类不能被实例化,只有继承它的子类可以;
extends 抽象类和 implements 的区别:
如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话,我们就用 extends 继承抽象类;
如果只是把抽象类当做标准的话,我们就用 implements 实现抽象类;
1 2 3 4 5 6 7 8 abstract class Animal { eat(); run(); printInfo() { print ('我是一个抽象类里面的普通方法' ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 import 'Animal.dart' ;class Dog extends Animal { @override eat() { print ("Dog eat ..." ); } @override run() { print ("Dog run ..." ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 import 'Animal.dart' ;class Cat extends Animal { @override eat() { print ("Cat eat ..." ); } @override run() { print ("Cat run ..." ); } }
1 2 3 4 5 6 7 8 9 10 11 12 import 'Cat.dart' ;import 'Dog.dart' ;main() { Dog d = new Dog(); d.eat(); d.printInfo(); Cat c = new Cat(); c.eat(); c.printInfo(); }
多态
允许将子类类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行效果;
子类的实例赋值给父类的引用;
多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现;
1 2 3 4 5 6 7 8 9 10 11 import 'Animal.dart' ;import 'Cat.dart' ;import 'Dog.dart' ;main() { Animal d = new Dog(); d.eat(); Animal c = new Cat(); c.eat(); }
接口 和 Java 一样,Dart 也有接口,但是和 Java 还是有区别的:
Dart 的接口没有 interface 关键字定义接口,而是普通类或抽象类都可以作为接口被实现;
同样使用 implements 关键字进行实现;
Dart 的接口有点奇怪,如果实现的类是普通类,需要将普通类中抽象的属性和方法全部覆写一遍;
因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像 Java 接口那样的方式,一般会使用抽象类;
建议使用抽象类定义接口;
一个类可以实现多个接口。
1 2 3 4 5 6 abstract class DB { String uri; insert(String data); delete(String id); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import 'DB.dart' ;class MySQL implements DB { @override String uri; @override insert(String data) { print ("MySQL insert" ); } @override delete(String id) { print ("MySQL delete" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import 'DB.dart' ;class MsSQL implements DB { @override String uri; @override insert(String data) { print ("MsSQL insert" ); } @override delete(String id) { print ("MsSQL delete" ); } }
1 2 3 4 5 6 7 import 'DB.dart' ;import 'MySQL.dart' ;main() { DB db = new MySQL(); db.insert('123456' ); }
mixins mixins 的中文意思是混入,就是在类中混入其他功能。
在 Dart 中可以使用 mixins 实现类似多继承 的功能。
因为 mixins 使用的条件,随着 Dart 版本一直在变,这里讲的是 Dart 2.x 中使 用 mixins 的条件:
作为 mixins 的类只能继承自 Object, 不能继承其他类;
作为 mixins 的类不能有构造函数;
一个类可以 mixins 多个 mixins 类;
mixins 绝不是继承,也不是接口,而是一种全新的特性;
mixins 的实例类型就是其超类的子类型。mixins 使用 with
关键字实现其功能。
1 2 3 4 5 6 class A { String info = "this is A" ; printA() { print ("A" ); } }
1 2 3 4 5 class B { printB() { print ("B" ); } }
1 2 3 4 5 6 7 import 'A.dart' ;import 'B.dart' ;import 'Person.dart' ;class C extends Person with A , B { C(String name, num age) : super (name, age); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import 'A.dart' ;import 'B.dart' ;import 'C.dart' ;main() { var c = new C("张三" , 20 ); c.printA(); c.printB(); print (c.info); c.printInfo(); print (c is C); print (c is A); print (c is B); }
泛型 通俗理解:泛型就是解决类、接口、方法的复用性、以及对不特定数据类型的支持(类型校验)。
泛型方法 1 2 3 4 5 6 7 8 9 10 11 12 13 main() { print (getData(1 )); print (getData2(2 )); } getData<T>(T value) { return "A" ; } T getData2<T>(T value) { return value; }
泛型类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 main() { PrintClass p = new PrintClass<int >(); p.add(1 ); p.add(2 ); p.add(3 ); p.printInfo(); } class PrintClass <T > { List list = new List <T>(); void add(T value) { this .list.add(value); } void printInfo() { for (var i = 0 ; i < this .list.length; i++) { print (this .list[i]); } } }
泛型接口 需求:实现数据缓存的功能。有文件缓存和内存缓存,内存缓存和文件缓存按照接口约束实现。
定义一个泛型接口,约束实现它的子类必须有 getByKey(key) 和 setByKey(key,value);
要求 setByKey 的时候的 value 的类型和实例化子类的时候指定的类型一致;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 main() { MemoryCache m = MemoryCache<Map >(); m.setByKey("index" , {"name" : "张三" , "age" : 20 }); } abstract class Cache <T > { getByKey(String key); void setByKey(String key, T value); } class MemoryCache <T > implements Cache <T > { @override getByKey(String key) { return null ; } @override void setByKey(String key, T value) { print ("我是内存缓存,把 key = ${key} value = ${value} 写入到了内存中" ); } } class FileCache <T > implements Cache <T > { @override getByKey(String key) { return null ; } @override void setByKey(String key, T value) { print ("我是文件缓存,把 key = ${key} value = ${value} 写入到了文件中" ); } }
库 在 Dart 中,库的使用是通过 import
关键字引入的。library 指令可以创建一个库,每个 Dart 文件都是一个库,即使没有使用 library 指令来指定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Dart 中的库主要有三种: 1 、我们自定义的库 import 'lib/xxx.dart' ; 2 、系统内置库 import 'dart:math' ; import 'dart:io' ; import 'dart:convert' ; 3 、pub 包管理系统中的库 https: https: https: 1 、需要在自己项目根目录新建一个 pubspec.yaml 2 、在 pubspec.yaml 文件配置名称、描述、依赖等信息 3 、然后运行 pub get 获取包下载到本地 4 、项目中引入库 import 'package:http/http.dart' as http; 看文档使用
导入自己本地库 1 2 3 4 5 6 import 'Person.dart' ;main() { var p = new Person("张三" , 20 ); p.printInfo(); }
导入系统内置库 1 2 3 4 5 6 import 'dart:math' ;main() { print (max(10 , 20 )); print (min(-1 , -2 )); }
导入系统内置库实现请求数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import 'dart:convert' ;import 'dart:io' ;main() async { var result = await getDataFromZhihuAPI(); print (result); } getDataFromZhihuAPI() async { var httpClient = new HttpClient(); var uri = new Uri .http('news-at.zhihu.com' , '/api/3/stories/latest' ); var request = await httpClient.getUrl(uri); var response = await request.close(); return await response.transform(utf8.decoder).join(); }
async 和 await 这两个关键字的使用只需要记住两点:①、只有 async 方法才能使用 await 关键字调用方法;②、如果调用别的 async 方法必须使用 await 关键字;
async 是让方法变成异步,await 是等待异步方法执行完成。
1 2 3 4 5 6 7 8 main() async { var result = await testAsync(); print (result); } testAsync() async { return "testAsync" ; }
导入 pub 包管理系统中的库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 pub 包管理系统: 1 、从下面网址找到要用的库 https: https: https: 2 、创建一个 pubspec.yaml 文件,内容如下 name: xxx description: A new flutter module project. dependencies: date_format: ^1.0 .9 3 、配置 dependencies4 、运行 pub get 获取远程库5 、看文档引入库使用
1 2 3 4 5 import 'package:date_format/date_format.dart' ;main() { print (formatDate(DateTime (1989 , 02 , 21 ), [yyyy, '-' , mm, '-' , dd])); }
库重命名与冲突解决 1 2 3 4 5 6 7 8 9 当引入两个库中有相同名称标识符的时候,如果是 Java, 通常我们通过写上完整的包名路径来指定使用的具体标识符,甚至不用 import 都可以, 但是 Dart 里面是必须 import 的。当冲突的时候,可以使用 as 关键字来指定库的前缀。如下例子所示: import 'package:lib1/lib1.dart' ;import 'package:lib2/lib2.dart' as lib2;Element element1 = new Element (); lib2.Element element2 = new lib2.Element ();
部分导入 1 2 3 4 5 6 7 8 9 如果只需要导入库的一部分,有两种模式: 模式一:只导入需要的部分,使用 show 关键字,如下例子所示: import 'package:lib1/lib1.dart' show foo;模式二:隐藏不需要的部分,使用 hide 关键字,如下例子所示: import 'package:lib2/lib2.dart' hide foo;
MyMath.dart
1 2 3 4 5 6 7 getOne() { return "one" ; } getTwo() { return "two" ; }
1 2 3 4 5 6 import 'MyMath.dart' show getOne;main() { print (getOne()); }
延迟加载 1 2 3 4 5 6 7 8 9 10 11 12 13 延迟加载也称为懒加载,可以在需要的时候再进行加载。 懒加载的最大好处是可以减少 APP 的启动时间。 懒加载使用 deferred as 关键字来指定,如下例子所示: import 'package:deferred/hello.dart' deferred as hello;当需要使用的时候,需要使用 loadLibrary() 方法来加载: greet() async { await hello.loadLibrary(); hello.printGreeting(); }
2.13 之后的一些新特性 Null safety 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 String? getData(apiUrl) { if (apiUrl != null ) { return "this is server data" ; } return null ; } void printLength(String? str) { try { print (str!.length); } catch (e) { print ("str is null" ); } } void main() { String? str = "abc" ; str = null ; print (str); print (getData("http://www.baidu.com" )); print (getData(null )); String? str2 = "this is str" ; print (str2!.length); printLength("str" ); printLength(null ); }
late 关键字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Person { late String name; late int age; void setInfo(String name, int age) { this .name = name; this .age = age; } String getInfo() { return "${this .name} ---${this .age} " ; } } void main(args) { Person p = new Person(); p.setInfo("张三" , 20 ); print (p.getInfo()); }
required 关键字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 String printInfo(String username, {int age = 10 , String sex = "男" }) { return "姓名:$username ---性别:$sex --年龄:$age " ; } String printInfo2(String username, {required int age, required String sex}) { return "姓名:$username ---性别:$sex --年龄:$age " ; } void main(args) { print (printInfo('张三' )); print (printInfo('张三' , age: 20 , sex: "女" )); print (printInfo2('张三' , age: 22 , sex: "女" )); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Person { String? name; int age; Person({this .name, required this .age}); String getInfo() { return "${this .name} ---${this .age} " ; } } void main(args) { Person p = new Person(name: "张三" , age: 20 ); print (p.getInfo()); Person p1 = new Person(age: 20 ); print (p1.getInfo()); }
性能优化 回顾 Dart 常量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void main() { final a; a = 13 ; print (a); final d = new DateTime .now(); }
const、identical 函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 void main() { const c = [2 ]; const d = [3 ]; print (identical(c, d)); }
普通构造函数 1 2 3 4 5 6 7 8 9 10 11 class Container { int width; int height; Container({required this .width, required this .height}); } void main() { var c1 = new Container(width: 100 , height: 100 ); var c2 = new Container(width: 100 , height: 100 ); print (identical(c1, c2)); }
常量构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Container { final int width; final int height; const Container({required this .width, required this .height}); } void main() { var c1 = Container(width: 100 , height: 100 ); var c2 = Container(width: 100 , height: 100 ); print (identical(c1, c2)); var c3 = const Container(width: 100 , height: 100 ); var c4 = const Container(width: 100 , height: 100 ); print (identical(c3, c4)); var c5 = const Container(width: 100 , height: 110 ); var c6 = const Container(width: 120 , height: 100 ); print (identical(c5, c6)); }