Flutter 实战之dart语言

本文探讨了Dart语言的JIT和AOT编译机制,解释了它们在开发和发布期的作用,以及热重载的五个步骤。此外,还介绍了Dart的继承、接口实现和混入特点,以及?.、??=、??运算符和类型检查的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

2、dart语言的内存分配与垃圾回收
(1)内存分配策略:在堆上移动指针,内存的增长是线性的。
(2)垃圾回收策略:多生代算法。新生代在回收内存时采用半空间机制,触发垃圾回收的时候,dart会将当前半空间中的活跃对象拷贝到备用空间,然后整体释放当前空间的所有内存。回收过程中,Dart中只需要操作少量的活跃对象。
3、dart与js一样 是单线程模式,所以dart中没有线程,只有isolate隔离区。隔离区之间不会共享内存,就像几个运行在不同进程中的worker,通过event looper在时间队列中传递消息通信。
一、Dart的语法
1、定义变量
定义变量有两种方法,一种是使用var来声明一个变量,类型交由编译器去推断。一种是使用特定的类型来声明这个变量。需要注意的是Flutter2 全面使用null safety,需要在声明时候初始化这个变量的值,如果在声明的时候没有初始化,需要用在语句前添加late,表示这个变量稍后会初始化,所以一定要注意,在使用变量之前就要确定这个变量是否已经被初始化了。
需要注意的是 变量仅存储对象的引用。
比如下面的int x = 1;这里的x是存储了一个int类型的对象饮用,1是这个对象的值。
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

2、函数
dart 函数中提供了可选命名参数和可选参数,在定义函数的时候,给参数添加{},以param:value的方式指定调用参数,也就是可选命名参数,给参数增加[],则意味着这些参数是可以忽略的,也就是可选参数。
//要达到可选命名参数的用法,那就在定义函数的时候给参数加上 {}
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

3、类
dart中类的成员变量没有public protected、private,只要在前面加上_就可以作为private方法使用;
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;
  }
}

在 Dart中,你可以对同一个父类进行继承或者接口实现以及混入。
  • 继承父类,会自动获取父类的成员变量和方法实现,子类可以根据需要覆写构造函数以及父类的方法
  • 接口实现,子类获取到的知识接口的成员变量符号和方法符号,需要重写成员变量,以及方法的声明和初始化。
  • 混入就是一个累可以以非继承的方式使用其他类中的变量与方法。
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

4、运算符
dart中有几个额外的运算符
  • ?. 运算符:它的意思是左边如果为空返回 null,否则返回右边的值。
  • ??=;b??=value;如果b为空,则把value 赋值给b;否则b的值不变。
  • ??;expr1 ?? expr2;如果 expr1 是 non-null, 返回 expr1 的值; 否则, 执行并返回 expr2 的值。
  • as 用来返回对象是否是这个类型
  • is 用来判断变量是否为某个类型
  • is! 如果变量不是这个类型,返回true
5、作用域 Dart的作用域是在花括号内。
6、在空安全下 dart的使用
(1)如果定义一个变量,但是这个变量的值有可能为空的时候,在类型后加上一个?代表变量可空
// 报错提示,因为泛型 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.’);

}

(3)late关键字
当使用late放在变量声明的前面,告诉Dart以下信息
  • 先不要给变量赋值。
  •  稍后将为它赋值
  •  你会在使用前对这个变量赋值。
  •  如果在给变量赋值之前读取该变量,则会抛出一个错误。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值