main方法
main(){ print("有返回值"); } void main() { print("没有返回值"); }
字符串的定义的方式
//字符串定义的几种方式 var str1 = "this is str1"; var str2 = "this is str2"; //2.字符串的拼接 2 种 var str3 = str1 + str2; print("$str1 $str2"); //字符串 双引号与单引号三个
list类型
//创建list var l1 = [1,3,5]; print(l1[1]); //创建指定类型的list var l2 = <String>["123","ecfff"]; //定义一个null的list var l3 = []; // 创建固定长度的list var l5 =List.filled(4, "");
map类型
//第一种定义map的方式 var person = {"name":"张三丰","age":180,"work":["程序员","外卖员"]}; print(person); print(person["name"]); //创建新的map var p = new Map(); p["name"]="李四"; print(p);
is 关键字来判断类型
// Dart 判断数据类型 //is 关键字来判断类型 var a1 = "ssssssss"; var a2 = 4.0; print(a1 is String); //true print(a2 is int); //false print(a2 is double); //true
算数运算符
int a =5; int b = 3; print(a/b); //1.6666666666666667 print(a%b); //2 print(a~/b); //1
逻辑运算符
// !取反 // &&并且 // ||或者
基础赋值运算符
//1.基础赋值运算符 = ??= //b ?? =23 表示如果b为null 把23赋值给b //2.复合赋值运算符 += -= *= /= %= ~/= var c=13; c+=10; //表示c = c+10
条件表达式
int a =5; int b = 3; print(a/b); //1.6666666666666667 print(a%b); //2 print(a~/b); //1
算数运算符
int a =5; int b = 3; print(a/b); //1.6666666666666667 print(a%b); //2 print(a~/b); //1 //1. if (a>b) { } else { } //2 switch var sex ="男1"; switch (sex) { case "男" : print("这是男"); break; default: print("传入参数错误"); break; } //2、 三目运算符 String vv = 1>2 ? '我是true' : '我是FALSE'; print(vv); //3、 ?? 运算符 // b ?? =23 表示如果b为null 把23赋值给b
类型转换
//1、Number与string类型之间的转换 //Number类型转换成string类型 tostring() // string类型转成Number类型parse String str= '123'; var myNum=int.parse( str); print(myNum is int); //true //如何str 为null 就会报错 处理方法 String str= ''; try{ var myNum=int.parse( str); print(myNum is int); //true }catch(e){ print("报错"); } // 2、其他类型转换成Booleans类型 // isEmpty :判断字符串是否为空 var str=' '; if(str.isEmpty){ print( 'str空'); }else{ print( 'str不为空'); } //判断是否为 NaN var myNum=0/0; print(myNum); if(myNum.isNaN){ print( 'Nan '); }
循环语句
while 和 do while的有区别
continue;跳过当前循环体然后循环还会继续执行
break;跳出循环体
List里面常用的属性和方法:
常用属性:
length; 长度 reversed; 翻转 isEmpty; 是否为空 isNotEmpty; 是否不为空
常用方法:
add 增加 addAll;
拼接数组 indexof ;
查找传入具体值 remove ;
删除传入具体值 removeAt;
删除传入索引值 fillRange;
修改 insert(index, value);
指定位置插入 insertAl1(index,list);
指定位置插入List toList() ;
其他类型转换成List join() ;
List转换成字符串 split() ;
字符串转化成List
常用的循环数据的方式
forEach map where any every
var list = ["123","张三","李四"]; list.forEach((value){ print("----------$value"); });
map
var list = [2,888,34]; var newList = list.map((value){ return value*2; }); print(newList.toList()); //[4, 1776, 68]
any
List myList=[1,3,4,5,7,8,9]; var f=myList.any((value){ //只要集合里面有满足条件的就返回true return value>9; }); print(f);
every
List myList=[1,3,4,5,7,8,9]; var f=myList.every((value){ //集合里面都满足条件的就返回true return value>1; }); print(f);
自定义方法
void main() { printInfo(); String printString(){ return 'this is str'; } print(printString()); var ss = printString(); print(ss); } void printInfo(){ print("111111111111"); // 111111111111 // this is str // this is str }
定义一个带可选参数的方法
void main() { print(printUserInfo('2222',2)); } String printUserInfo(String username,[int ? age]){//行参 if(age!= null){ return "姓名:$username---年龄:$age"; } return "姓名:$username---年龄保密"; }
定义一个带默认参数的方法[]
void main() { print(printUsersInfo('2222',1)); } String printUsersInfo(String username,[int ? age,String ? sex='男']){//行参 if(age!= null){ return "姓名:$username---年龄:$age------性别 $sex"; } return "姓名:$username---年龄保密"; }
定义一个命名参效的方法{}
void main() { print(printUserInfo('2222',age:1)); } String printUserInfo(String username,{int ? age,String ? sex='男'}){//行参 if(age!= null){ return "姓名:$username---年龄:$age------性别 $sex"; } return "姓名:$username---年龄保密"; }
实现一个把方法当做参数的方法
void main() { fn2(fn1); } fn1(){ print("fn16666666"); } fn2(fn){ fn(); }
自执行方法
(() { print('我是自执行方法'); })(); ((int n) { print(n); print('我是自执行方法'); })(12);
箭头函数
void main() { var list = ["123","张三","李四"]; list.forEach((value)=> { print(value) }); }
1、全局变量特点: 全局变量常驻内存、全局变量污染全局
2、局部变量的特点: 不常驻内存会被垃圾机制回收、不会污染全局
想实现的功能:
1.常驻内存 2.不污染全局 产生了闭包,闭包可以解决这个问题..... 闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包。
fn() { var a = 123; /*不会污染全局 常驻内存*/ return () { a++; print(a); }; } var b = fn(); b(); b(); b();
类与对象
dart是面向对象的编程
自定义类
class PerSion{ String name = '李四'; int age = 44; void getInfo(){ print("${this.name}==========${this.age}"); } } void main() { //实例化 var P1 = new PerSion(); print(P1.name); P1.getInfo(); // 李四 // 李四==========44 }
命名构造函数
class PerSion{ String name = '李四'; int age = 44; PerSion(this.name); PerSion.onw(){ print("这是一个命名函数"); } void getInfo(String name){ print("${name}==========${this.age}"); } } void main() { new PerSion.onw(); //这是一个命名函数 }
把类单独抽成一个文件
import 'lib/Person.dart';
私有方法前加‘_’,并且单独抽成一个文件 才会生效(间接公有调私有)
get与set
class PerSion{ num height; num width; PerSion(this.height,this.width); area(){ return this.height*this.width; } set areaHeight(value){ this.height = value; } get areas{ return this.height*this.width; } } void main() { PerSion p = new PerSion(10,4); print("面积:${p.area()}"); //面积:40 p.areaHeight=2; print("面积_:${p.area()}"); //面积_:8 print("面积_2:${p.areas}"); //面积_2:8 }
构造函数体运行之前初始化实例变量
class PerSion{ num height; num width; PerSion():height=5,width=10; area(){ return this.height*this.width; } } void main() { PerSion p = new PerSion(); print(p.area()); //50 }
Dart中的对象操作符:
? 条件运算符(了解) as 类型转换 is 类型判断 .. 级联操作(连缀) Person p1 = new Person(); p1..name = "李四" ..age = 20 ..printInfo();
类的继承
1.子类使用extends关键词来继承父类 2.子类会继承父类里面可见的属性和方法,但是不会继承构造函数 3.子类能复写父类的方法 getter和setter ( @override // 可以写 可以不写)
super关键字的使用
class Person { String name; num age; Person(this.name, this.age); void printInfo() { print('${this.name}----${this.age}'); } } class Web extends Person { Web(String name, num age) : super(name, age); } main() { Web w = new Web('年龄:', 12); w.printInfo(); // 年龄----12 }
Dart抽象类
使用关键字 abstract
标识类可以让该类成为 抽象类,抽象类将无法被实例化
abstract class Animal { speak(); /// 抽象方法, 子类必须实现该方法 printInfo() { /// 不是抽象方法, 子类不需要实现 print('---- Animal, not abstract method'); /// 调用了speak方法 speak(); } } class Dog extends Animal{ @override speak() { print('---- Dog, 实现了抽象方法speak'); } } void main() { Dog d1 = Dog(); d1.speak(); d1.printInfo(); /// 方法内部调用了speak()方法 }
dart接口
/* 和Java一样,dart也有接口,但是和Java还是有区别的。 首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。 同样使用implements关键字进行实现。 但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。 而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。 建议 使用抽象类定义接口。 */ /* 定义一个DB库 支持 mysql mssql mongodb mysql mssql mongodb三个类里面都有同样的方法 */ abstract class Db{ //当做接口 接口:就是约定 、规范 String uri; //数据库的链接地址 add(String data); save(); delete(); } class Mysql implements Db{ @override String uri; Mysql(this.uri); @override add(data) { // TODO: implement add print('这是mysql的add方法'+data); } @override delete() { // TODO: implement delete return null; } @override save() { // TODO: implement save return null; } remove(){ } } class MsSql implements Db{ @override String uri; @override add(String data) { print('这是mssql的add方法'+data); } @override delete() { // TODO: implement delete return null; } @override save() { // TODO: implement save return null; } } main() { Mysql mysql=new Mysql('xxxxxx'); mysql.add('1243214'); }
extends抽象类和implements的区别:
1、如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类 2、如果只是把抽象类当做标准的话我们就用implements实现抽象类
一个类实现多个接口
class C implements A,B{}
在Dart中可以使用mixins实现类似多继承的功能
因为mixins使用的条件,随着Dart版本一直在变,这里讲的是Dart2.x中使用mixins的条件: 1、作为mixins的类只能继承自object,不能继承其他类 2、作为mixins的类不能有构造函数 3、一个类可以mixins多个mixins类 4、mixins绝不是继承,也不是接口,而是一种全新的特性
class C with A,B{}
泛型
泛型就是解决类接口方法的复用性、以及对不特定数据类型的支持(类型校验)
T getDate<T>(T value){ return value; } void main() { print(getDate(22)); //22 print(getDate<String>("张三")); //张三 print(getDate<int>(22)); //22 }
泛型类
实现数据缓存的功能:有文件缓存、和内存缓存:内存缓存和文件缓存按照接口约束实现。
Dart中的库主要有三种:
1、自定义的库
import 'lib/xxx.dart';
2、系统内置库
import 'dart:math'; import 'dart:io'; import 'dart:convert';
3、第三方库——Pub包管理系统中的库
需要在自己想项目根目录新建一个pubspec.yaml
在pubspec.yaml文件 然后配置名称 、描述、依赖等信息 然后运行 pub get 获取包下载到本地 项目中引入库 import 'package:http/http.dart' as http; 看文档使用
1、从下面网址找到要用的库
https : // pub.dev/ packages
https ://pub.flutter-io.cn/packages
https:// pub.dartlang.org/flutter/
2、创建一个pubspec.yaml文件,内容如下
name: xxx description: A new flutter module project. dependencies: http: ^0.12.0+2 date_format: ^1.0.6
3、配置dependencies
4、运行pub get 获取远程库
5、看文档引入库使用
async和await
这两个关键字的使用只需要记住两点:
只有async方法才能使用await关键字调用方法
如果调用别的async方法必须使用await关键字
async是让方法变成异步。
await是等待异步方法执行完成。
Dart库的重命名 Dart冲突解决
import 'lib/Person1.dart'; import 'lib/Person2.dart' as lib; main(List<String> args) { Person p1=new Person('张三', 20); p1.printInfo(); lib.Person p2=new lib.Person('李四', 20); p2.printInfo();
部分引入库
/* 部分导入 如果只需要导入库的一部分,有两种模式: 模式一:只导入需要的部分,使用show关键字,如下例子所示: import 'package:lib1/lib1.dart' show foo; 模式二:隐藏不需要的部分,使用hide关键字,如下例子所示: import 'package:lib2/lib2.dart' hide foo; */ // import 'lib/myMath.dart' show getAge;
延迟加载
/* 延迟加载 也称为懒加载,可以在需要的时候再进行加载。 懒加载的最大好处是可以减少APP的启动时间。 懒加载使用deferred as关键字来指定,如下例子所示: import 'package:deferred/hello.dart' deferred as hello; 当需要使用的时候,需要使用loadLibrary()方法来加载: greet() async { await hello.loadLibrary(); hello.printGreeting(); } */
Null safety
/* Null safety翻译成中文的意思是空安全。 null safety 可以帮助开发者避免一些日常开发中很难被发现的错误,并且额外的好处是可以改善性能 Flutter2.2.0 (2021年5月19日发布)之后的版本都要求使用null safety。 ?可空类型 !类型断言 */
?可空类型
void main() { String? username = "张三"; int? age =8; username = null; age = null; }
!类型断言
void main() { String? username = "张三"; int? age =8; username = null; age = null; print("username:${username}"); //username:null print("age:${age}"); //age:null print(username !.length); //如果username为null 抛异常 }
late关键字主要用于延迟初始化
class getLate{ late String name; }
required关键词
主要用于允许根据需要标记任何命名参数(函数或类),使得 它们不为空。因为可选参数中必须有个 require
void debugger({required String message}) {}
Dart 性能优化之常量、常量构造函数详解
/* Dart常量:final 和const修饰符 const声明的常量是在编译时确定的,永远不会改变 final声明的常量允许声明后再赋值,赋值后不可改变,final 声明的变量是在运行时确定的 final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化 const关键词在多个地方创建相同的对象的时候,内存中只保留了一个对象 */
identical函数 :检查两个引用是否指向同一个对象
void main() { var o1 = new Object(); var o2 = new Object(); print(identical(o1, o2)); //false print(identical(o1, o1)); //true } //表示实例化常量构造函数 //o1和 o2共享了存储空间 void main() { var o1 = const Object(); var o2 = const Object(); print(identical(o1, o2)); //true print(identical(o1, o1)); //true }
dart中普通构造函数
class Container{ int width; int height; Container({required this.width,required this.height}); } void main() { var o1 = new Container(width: 100,height: 20); var o2 = new Container(width: 100,height: 20); print(identical(o1, o2)); //false print(identical(o1, o1)); //true }
dart中常量构造函数
/** 1、常量构造函数需以const关键字修饰 2、const构造函数必须用于成员变量都是final的类 3、如果实例化时不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例 4、实例化常量构造函数的时候,多个地方创建这个对象,如果传入的值相同,如果传入的值相同,只会保留一个对象 5、Flutter中const修饰不仅仅是节省组件构建时的内存开销,Flutter 在需要重新构建const组件是不应该改变的,重新构建没有任何意义,因此·Flutter·不会重建构建·const·组件 */ class Container{ final int width; final int height; const Container({required this.width,required this.height}); } void main() { var o1 = new Container(width: 100,height: 20); var o2 = new Container(width: 100,height: 20); print(identical(o1, o2)); //false print(identical(o1, o1)); //true var o3 = const Container(width: 100,height: 20); var o4 = const Container(width: 100,height: 20); print(identical(o3, o4)); //true print(identical(o3, o4)); //true }