1、了解dart语言之前,先要理解一下什么是JIT和AOT。
(1)JIT (just in time)即时编译。在开发周期中使用,可以动态下发和执行代码,开发测试效率高,但运行速度和执行性能会因为运行时即时编译受到影响。
(2)AOT (ahead of time)运行前编译。提前编译,可以生成被直接执行的二进制代码,运行速度快、执行性能表现好,但每次执行前都需要提前编译,开发测试效率低。
在开发期间使用JIT编译,发布期使用AOT。flutter基于这两个机制,使得开发效率高,发布时执行快性能好。
总体来说,热重载的流程可以分为扫描工程改动、增量编译、推送更新、代码合并、widget重建5个步骤
-
工程改动:热重载模块会逐一扫描工程中的文件,检查是否有新增、删除或者改动,直到找到在上次编译之后,发生变化的dart代码。
-
增量编译:热重载模块会将发生变化的Dart代码,通过编译转化为增量的Dart Kernel文件
-
推送更新:将Dart kernel文件通过http接口发送给设备中的dart Vm
-
代码合并: dart vm会将收到的增量的dart kernel文件与原来的文件进行合并,然后重新加载新的dart kernel文件
-
widget重建:在确定dart vm资源加载成功后,flutter会将其UI线程重置,通知Flutter Framework重建widget
int x = 1;
int hex = 0xEEADBEEF;
double y = 1.1;
double exponents = 1.13e5;
int roundY = y.round();
var a = ‘’;
String b = ‘hello krys’;
bool flag = true;
var arr1 = ["Tom", "Andy", "Jack"];
var arr2 = List.of([1,2,3]);
arr2.add(499);
arr2.forEach((v) => print('${v}'));
//List
var arr1 = <String>['Tom', 'Andy', 'Jack'];
var arr2 = new List<int>.of([1,2,3]);
arr2.add(499);
arr2.forEach((v) => print('${v}'));
print(arr2 is List<int>); // true
//Map
var map1 = <String, String>{'name': 'Tom','sex': 'male',};
var map2 = new Map<String, String>();
map2['name'] = 'Tom';
map2['sex'] = 'male';
map2.forEach((k,v) => print('${k}: ${v}'));
//Set
var elements = <String>{};
elements.add('fluorine');
elements.addAll(halogens);
print(map2 is Map<String, String>); // true
//要达到可选命名参数的用法,那就在定义函数的时候给参数加上 {}
void enable1Flags({bool bold, bool hidden}) => print("$bold , $hidden");
//定义可选命名参数时增加默认值
void enable2Flags({bool bold = true, bool hidden = false}) => print("$bold ,$hidden");
//可忽略的参数在函数定义时用[]符号指定
void enable3Flags(bool bold, [bool hidden]) => print("$bold ,$hidden");
//定义可忽略参数时增加默认值
void enable4Flags(bool bold, [bool hidden = false]) => print("$bold ,$hidden");
//可选命名参数函数调用
enable1Flags(bold: true, hidden: false); //true, false
enable1Flags(bold: true); //true, null
enable2Flags(bold: false); //false, false
//可忽略参数函数调用
enable3Flags(true, false); //true, false
enable3Flags(true,); //true, null
enable4Flags(true); //true, false
enable4Flags(true,true); // true, true
class NetUtils {
static String Host = 'http://192.168.0.36:3001';
static String getProductList = Host + '/v1/product/getProductList';
static String Login = Host +'/v1/user/login';
static String bingeDevice = Host + '/v1/equip/bindDevice';
static String getBindDevice = Host + '/v1/equip/getBindProductList';
static Future get(String url, Map<String, dynamic> params) async {
var response;
//PersistCookieJar是保存在文件里,退出appcookie还在;cookiejar是保存在内存里,退出app就不在了
dio.interceptors.add(CookieManager(PersistCookieJar()));
response = await dio.get(url, queryParameters: params);
return response.data;
}
static Future post(String url, Map<String, dynamic> params) async {
var dio = Dio();
var cookieJar=CookieJar();
dio.interceptors.add(CookieManager(cookieJar));
var response = await dio.post(url, data: params);
return response.data;
}
}
-
继承父类,会自动获取父类的成员变量和方法实现,子类可以根据需要覆写构造函数以及父类的方法
-
接口实现,子类获取到的知识接口的成员变量符号和方法符号,需要重写成员变量,以及方法的声明和初始化。
-
混入就是一个累可以以非继承的方式使用其他类中的变量与方法。
class Point {
num x = 0, y = 0;
void printInfo() => print('($x,$y)');
}
//Vector继承自Point
class Vector extends Point{
num z = 0;
@override
void printInfo() => print('($x,$y,$z)'); //覆写了printInfo实现
}
//Coordinate是对Point的接口实现
class Coordinate implements Point {
num x = 0, y = 0; //成员变量需要重新声明
void printInfo() => print('($x,$y)'); //成员函数需要重新声明实现
}
var xxx = Vector();
xxx
..x = 1
..y = 2
..z = 3; //级联运算符,等同于xxx.x=1; xxx.y=2;xxx.z=3;
xxx.printInfo(); //输出(1,2,3)
var yyy = Coordinate();
yyy
..x = 1
..y = 2; //级联运算符,等同于yyy.x=1; yyy.y=2;
yyy.printInfo(); //输出(1,2)
print (yyy is Point); //true
print(yyy is Coordinate); //true
class Coordinate with Point {
}
var yyy = Coordinate();
print (yyy is Point); //true
print(yyy is Coordinate); //true
-
?. 运算符:它的意思是左边如果为空返回 null,否则返回右边的值。
-
??=;b??=value;如果b为空,则把value 赋值给b;否则b的值不变。
-
??;expr1 ?? expr2;如果 expr1 是 non-null, 返回 expr1 的值; 否则, 执行并返回 expr2 的值。
-
as 用来返回对象是否是这个类型
-
is 用来判断变量是否为某个类型
-
is! 如果变量不是这个类型,返回true
// 报错提示,因为泛型 String 表示非 null
List<String> aListOfNullableStrings = ['one', null, 'three’];
// 数组元素允许为空,所以不再报错
List<String?> aListOfNullableStrings = ['one', null, 'three'];
(2)如果确定某个可为空的表达式非空,那么使用空断言操作符!使Dart将其视为非空。
/// 这个方法的返回值可能为空
int? couldReturnNullButDoesnt() => -3;
void main() {
int? couldBeNullButIsnt = 1;
List<int?> listThatCouldHoldNulls = [2, null, 4];
// couldBeNullButIsnt 变量虽然可为空,但是已经赋予初始值,因此不会报错
int a = couldBeNullButIsnt;
// 列表泛型中声明元素可为空,与 int b 类型不匹配报错
int b = listThatCouldHoldNulls.first; // first item in the list
// 上面声明这个方法可能返回空,而 int c 表示非空,所以报错
int c = couldReturnNullButDoesnt().abs(); // absolute value
// 添加 ! 断言 表示非空,赋值成功
int b = listThatCouldHoldNulls.first!; // first item in the list
int c = couldReturnNullButDoesnt()!.abs(); // absolute value
print('a is $a.');
print('b is $b.');
print('c is $c.’);
}
-
先不要给变量赋值。
-
稍后将为它赋值
-
你会在使用前对这个变量赋值。
-
如果在给变量赋值之前读取该变量,则会抛出一个错误。