Dart入口方法介绍
第一种
main(){
。。。
print('你好dart');
。。。
}
第二种:
voin main(){ //没有返回值
。。。
print('你好dart');
。。。
}
Dart注释方法
vscode里可以ctrl+/快速注释
/*
这是一个注释
*/
//这也是一个注释
///这还是一个注释
Dart变量
Dart 变量:
dart是一个强大的脚本类语言,可以不预先定义变量类型,自动会类型推倒(var)
dart中定义变量可以通过var关键字可以通过类型来申明变量
如:
var str='this is var;
String str='this is var';
int str=123;
注:var后就不要写类型,写了类型就不要写var,两者都写会报错
Dart命名规则
1.变量名称必须由数字、字母、下划线和美元符($)组成。
2.注意:标识符开头不能是数字
3.标识符不能是保留字和关键字。
4.变量的名字是区分大小写的如:age和Age是不同的变量。在实际的运用中,也建议,不要用一个
5、标识符(变量名称)一定要见名思意:变量名称建议用名词,方法名称建议用动词
Dart常量: final和const修饰符
const值不变 一开始就得赋值
final 可以开始不赋值 只能赋一次;而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化
√ final a = new DateTime.now() //获取当前的时间
× const a = new DateTiem.now()
永远不改量的量,请使用final或const修饰它,而不是使用var或其他变量类型。
Dart数据类型详解
常用数据类型:
Numbers(数值):
int 必须是整型
double 既可以是整型也可以是浮点型
Strings(字符串)
String
//1.字符串定义的几种方式
var str1 = 'this is str';
var str2 = "this is str";
虽然var可以识别字符串类型,但还是建议指定类型
Strng st1 = 'this is str';
Strng st2 = 'this is str';
还可以用三个单引号或双引号来输出多行字符串
Strng st1 = '''this is str
this is str
this is str
''';//这样就会输出三行字符串,而不会报错
Strng st2 = """this is str
this is str
this is str
"""
//字符串的拼接
Strng st1 = '你好';
Strng st2 = 'dart';
①print('$str1 $str2');
②print(str1 + str2);
printf(str1 + ' ' + str2);
Booleans(布尔)
bool 值true/false
List(数组/集合)
在Dart中,数组是列表对象,所以大多数人只是称它们为列表
//第一种定义List的方式
var l1 = ["张三".20.true];
l1.length //获取集合的长度
//第二种定义List的方式 指定类型
var l2 = <String>["张三","李四"];
//第三种定义List的方式 增加数据,通过[]创建的数据,他的容量是可以改变的
var l3 = []; //空集合
//l3.add(value);
l3.add("张三");
l3.add("李四");
l3.add(20);
//第四种定义List的方式 List.filled(length,fill)
var l6=new List();//在新版本的dart里面没法使用这个方法了
var l6=List.filled(length,fill);//创建一个固定长度的集合
var l6=List<指定类型>.filled(length,fill);
//这种方法创建的集合长度是无法被改变的
//但是用[]创建的集合是可以改变长度的
Maps(字典)
通常来说,Map是一个键值对相关的对象。键和值可以是任何类型的对象。
//第一种定义Maps的方式
var person={
"name":"张三",
"age":20,
"work":["程序员","送外卖"]
};
print(person);
print(person["name"]);
print(person["age"]);
print(person["work"]);
//第二种定义Maps的方式
var p = new Map();
p["name"]="李四";
p["age"]=22;
p["work"]=["程序员","送外卖"];
print(p);
项目中用不到的数据类型:
Runes
Rune是UTF-32编码的字符串。它可以通过文字转换成符号表情或者代表特定的文字。
main(){
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
}
Symbols
Symbol对象表示在Dart程序中声明的运算符或标识符。您可能永远不需要使用符号,但它们
在Dart中符号用#开头来表示,入门阶段不需要了解这东西,可能永远也用不上。
http://dart.goodev.org/guides/libraries/library-tour#dartmirrors—reflect
Dart判断数据类型
//is 关键词来判断类型
var str = '1234';
if(str is String){
print('是String类型');
}else if(str is int){
print('int');
}else{
print('其他');
}
Dart运算符
算数运算符
+ - * / ~/(取整) %(取余)
关系运算符
== != > < >= <=
逻辑运算符
! && ||
自增自减运算符
++ --
赋值运算符
1.基础赋值运算符:= ??=
//b??=23; 表示如果b为空,就把23赋给b
2.复合赋值运算符:+= -= *= /= %= ~/=
条件表达式
1.if else switch case
2.三目运算符(可以替换一些简单的if-else语句)
bool flag = true;
String c=flag?'我是true':'我是flase';
print(c);
3. ??运算符
var a;
var b = a ?? 10; //如果a为空,就把10赋给b,否则就直接把a赋给b
Dart类型转换
//1、Number与String类型之间的转换
// Number类型转换成String类型 toString()
var myNum=12;
var str=myNum.toString();
// String类型转成Number类型 int/double.parse()
String str='123';
var myNum=int.parse(str);
print(myNum is int);
String str='123.1';
var myNum=double.parse(str);
print(myNum is doubleD;
//建议String类型转换成Number类型的时候统一使用double,避免报错
//有的时候服务器传过来的是空字符串,如果这时还用double或者int的话也会报错,假设传过来的是空字符串,那我们想让他返回0,可以这么做
String price='';
try{
var myNum=double.parse(price);
print(myNum);
}catch(err){
print(0);
}
//2、其他类型转换成Booleans类型
// isEmpty:判断字符串是否为空
var str=''; //String类型转Boolean
if(str.isEmpty){
print('str空');
}else{
print('str不为空');
var myNum=123; //Number类型转Boolean
if(myNum==0){
print('0');
}else{
print('非0');
var myNum; //没赋值
if(myNum==null){
print('空');
}else{
print('非空');
var myNum=0/0;
// print(myNum); 会输出NaN,而不会报错
if(myNum.isNaN){
print('NaN');
Dart循环语句
//for基本语法
for(inti=1;i<=100;i++){
print(i);
//第一步,声明变量int i=1;
//第二步,判断i<=100
//第三步,print(i);
//第四步,i++
//第五步从第二步再来,直到判断为false
//while基本语法
语法格式:
while(表达式/循环条件){
}
do{
语句/循环体
}while(表达式/循环条件);
注意:1、最后的分号不要忘记
2、循环条件中使用的变量需要经过初始化
3、循环体中,应有结束循环的条件,否则会造成死循环。
//break和continue语句用法
break语句功能:
1、在switch语句中使流程跳出switch结构。
2、在循环语句中使流程跳出当前循环,遇到break循环终止,后面代码也不会执行
强调:
1、如果在循环中已经执行了break语句,就不会执行循环体中位于break后的语句。
2、在多层循环中,一个break语句只能向外跳出一层
break可以用在switch case中 也可以用在 for 循环和 while循环中
continue语句的功能:
【注】只能在循环语句中使用,使本次循环结束,即跳过循环体重下面尚未执行的语句,接着进行下continue可以用在for循环以及while循环中,但是不建议用在while循环中,不小心容易死循环
Dart List Set Map详解
//List里面常用的属性和方法:
常用属性:
length 长度
reversed 翻转
isEmpty 是否为空,为空返回true
isNotEmpty 是否不为空,不为空返回true
常用方法:
add 增加且只能增加一个数据
addA11 拼接数组
List myList=['香蕉','苹果','西瓜'];
//myList.add('桃子');//增加数据增加一个
myList.addA11(['桃子','葡萄']);
indexof 查找(下标/索引值) 传入具体值 查找不到返回-1 查找到返回索引值
print(myList.indexof('苹果'));
remove 删除 传入具体值
myList.remove('西瓜');
removeAt 删除 传入索引值
myList.removeAt(2);
fillRange 修改(左闭右开)
List myList=['香蕉','苹果','西瓜'];
// myList.fillRange(1,2,'aaa'); 修改了苹果
myList.fillRange(1,3,'aaa'); //修改了苹果和西瓜
print(myList);
insert(index,value); 指定位置插入
insertAll(index,list) 指定位置插入List
toList() 其他类型转换成List
join() List转换成字符串
split() 字符串转化成List
var str='香蕉-苹果-西瓜';
var list=str.split('-');//以'-'分割成数组
print(list);
print(list is List);
forEach
map
where
any
every
//Set
//用它最主要的功能就是去除数组重复内容
//Set是没有顺序且不能重复的集合,所以不能通过索引去获取值
var s=new Set();
s.add('香蕉');
s.add('苹果');
print(s);//{香蕉,苹果}
print ( s . toList ( ) ) ;//转List
//Maps(映射)
//两种定义方法
var person={
"name":"张三",
"age":20
}
var m=new Map();
m["name"]="李四";
//映射(Maps)是无序的键值对:
常用属性:
keys 获取所有的key值
Map person={
"name":"张三",
"age":20
}
print ( person . keys ) ;//(name,age)
values 获取所有的value值
Map person={
"name":"张三",
"age":20
}
print ( person . values ) ;//(张三,20)
isEmpty 是否为空
isNotEmpty 是否不为空
常用方法:
remove(key) 删除指定key的数据
addA11({...}) 合并映射给映射内增加属性
person.addAll({
"work":['敲代码','送外卖'],
"height":160
});
containsValue 查看映射内的值 返回true/false
forEach
//循环List
myList.forEach((value){
print("$value");
});
//循环Set
var s=new Set();
s.addA11([1,222,333]);
s.forEach((value)=>print(value));
//循环Map
Map person={
"name":"张三",
"age":20
person.forEach((key,value){
print("$key---$value");
});
map
List myList=[1,3,4];
var newList=myList.map((value){
return value*2;
});
print(newList); //(2,6,8)
where
List myList=[1,3,4,5,7,8,9];
var newList=myList.where((value){
return value>5;
});
print(newList.toList());//[7,8,9]
any//判断集合里有没有返回条件的,有就返回true,没有就返回flase
List myList=[1,3,4,5,7,8,9];
var f=myList.any((value){ //
return value>5;
});
print(f);//true
every//集合里每一个都要满足条件,才返回true,不然返回flase
List myList=[1,3,4,5,7,8,9];
var f=myList.every((value){ //
return value>5;
});
print(f);//flase
Dart的函数
内置方法/函数:
print();
自定义方法:
自定义方法的基本格式:
返回类型方法名称(参数1,参数2,…){
方法体
return返回值;}
void printInfo(){
print('我是一个自定义方法');
}
void main(){
//print('调用系统内置的方法');
printInfo();
int getNum(){
var myNum=123;
return myNum;
}
var n = getNum();
print(n);
}
//定义一个带可选参数的方法
String printUserInfo(String username, [int age, String sex]){//行参
if(age!=null){
return"姓名:$username---年龄: $age";
}
return "姓名:$username---年龄保密"
}
print(printUserInfo('张三',20));//实参
//定义一个带默认参数的方法
String printUserInfo(String username, [int age, String sex=='男']){//行参
if(age!=null){
return"姓名:$username---性别:$sex---年龄: $age";
}
return "姓名:$username---性别:$sex---年龄保密"
}
print(printUserInfo('张三',20));//实参 姓名:张三---性别:男--年龄保密
//5、定义一个命名参数的方法
String printUserInfo(String username,{int age,String sex='男'}){//行参
if(age!=null){
return"姓名:$username---性别:$sex--年龄:$age";
}
return"姓名:$username---性别:$sex--年龄保密";
}
print(printUserInfo('张三',age:20,sex:'未知'));//姓名:张三---性别:未知--年龄:20
//实现一个把方法当作参数的方法
Dart箭头函数
/*需求:使用forEach打印下面List里面的数据*/
List list=['苹果','香蕉','西瓜'];
//list.forEach((value){
// print(value);
//});
list.forEach((value)=>print(value));
or
list.forEach((value)=>{
print(value)
});
/*需求:修改下面List里面的数据,让数组中大于2的值乘以2*/
List list=[4,1,2,3,4];
//var newList=list.map((value){
//if(value>2){
//return value*2;
//}
//return value;
//})
//print(newList.toList());
var newList=list.map((value)=>value>2?value*2:value);
print(newList.toList());
/*
需求:1、定义一个方法isEvenNumber来判断一个数是否是偶数
2、定义一个方法打印1-n以内的所有偶数
*/
bool isEvenNumber(int n){
if(n%2==0){
return true;
}
return false;
}
printNum(int n){
for(var i=1;i<=n;i++){
if(isEvenNumber(i)){
print(i);
}
}
}
printNum(10);
Dart自执行方法
((){
print('我是自执行方法');
})();
Dart方法的递归
//通过方法的递归 求1-100的和
var sum=0;
fn(int n){
sum+=n;
if(n==0){
return;
}
fn(n-1);
}
fn(100);
Dart闭包
闭包:
1、全局变量特点:全局变量常驻内存、全局变量污染全局
2、局部变量的特点:不常驻内存会被垃圾机制回收、不会污染全局
- 想实现的功能:
1.常驻内存
2.不污染全局
产生了闭包,闭包可以解决这个问题…
闭包:函数嵌套函数,内部函数会调用外部函数的变量或参数,变量或参数不会被
闭包的写法:函数嵌套函数,并return里面的函数,这样就形成了闭包。
fn(){
var a=123;/*不会污染全局 常驻内存*/
return(){
a++;
print(a);
};
var b=fn();
b();
b();
b();
Dart 对象 类
Dart所有的东西都是对象,所有的对象都继承自0bject类。
Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是object的子类
一个类通常由属性和方法组成。
class Person{
String name="张三";
int age=23;
void getInfo(){
// print("$name----sage");
print("${this.name}----${this.age}");
}
void setInfo(int age){
this.age=age;
}
}
void main(){
//实例化
var p1=new Person();
//print(p1.name);
//p1.getInfo();
Persion p1=new Person();
print(p1.name);
p1.setInfo(28);
}
Dart的构造方法,构造函数
class Person{
String name="张三";
int age=23;
void getInfo(){
// print("$name----sage");
print("${this.name}----${this.age}");
}
//默认构造函数
Person(String name,int age){
this.name = name;
this.age = age;
print('这是构造函数里面的内容 这个方法在实例化的时候触发');
}
or
//Person(this.name,this.age);
void setInfo(int age){
this.age=age;
}
}
void main(){
//实例化
Person p1=new Person('张三',20);
p1.printInfo();
Person p2=new Person('李四',20);
p2.printInfo();
}
Dart 命名构造函数
class Person{
String name="张三";
int age=23;
void getInfo(){
// print("$name----sage");
print("${this.name}----${this.age}");
}
//Person(this.name,this.age);默认构造函数简写
Person.now(){
print('我是命名构造函数');
}
void setInfo(int age){
this.age=age;
}
}
void main(){
//Person p1=new Person('张三',20);//默认实例化类的时候调用的是默认构造函数
person p1 = new Person.now();
}
Dart的私有属性和私有方法
Dart和其他面向对象语言不一样,Data中没有 public private protected这些访问修饰符合
但是我们可以使用_把一个属性或者方法定义成私有,并且这个类必须抽离成一个单独的文件
#Dart 类中的getter和seter修饰符
//getter
class Rect{
num height;
num width;
Rect(this.height,this.width);
//area(){
//return this.height*this.width;
//}
get area{
return this.height*this.width;
}
}
void main(){
Rect r = new Rect(10,4);
//print("面积:${r.area()}");
print("面积:${r.area}")
}
//setter
class Rect{
num height;
num width;
Rect(this.height,this.width);
area(){
return this.height*this.width;
}
set areaHeight(value){
this.height=value;
}
}
void main(){
Rect r = new Rect(10,4);
//print("面积:${r.area()}");
r.areaHeight=6;
print("面积:${r.area()}")
}
Dart 类种的初始化列表
//Dart中我们也可以在构造函数体运行之前初始化实例变量
class Rect{
int height;
int width;
Rect():height=2,width=10{
}
getArea(){
return this.height*this.width;
}
}
void main(){
Rect r=new Rect();
print(r.getArea());
}
Dart 静态成员
//1、使用static关键字来实现类级别的变量和函数,静态成员和静态方法不能通过实例化来访问,只能通过类来访问
//2、静态方法不能访问非静态成员,非静态方法可以访问静态成员
class Person {
static String name ='张三';
int age=20;
static void show(){
print(name);
}
void printInfo(){/*非静态方法可以访问静态成员以及非静态成员*/
// print(name);//访问静态属性
// print(this.age);//访问非静态属性
show();//调用静态方法
}
static void printUserInfo(){//静态方法
print(name); //静态属性
show(); //静态方法
//print(this.age);//静态方法没法访问非静态的属性
//this.printInfo();//静态方法没法访问非静态的方法
printInfo();
}
}
Dart的对象操作符
/*
Dart中的对象操作符:
? 条件运算符(了解)
as 类型转换
is 类型判断
.. 级联操作(连缀) 重要!
*/
//? 条件运算符(了解)
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo(){
print("${this.name}---${this.age}");
}
}
main(){
// Person p;
// p?.printInfo(); //如果p为空,则不运行printInfo
}
//.. 级联操作(连缀) 重要!
// Person p1=new Person('张三1',20);
// p1.printInfo();
// p1.name='张三222';
// p1.age=40;
// p1.printInfo();
==
Person p1=new Person('张三1',20);
p1.printInfo();
p1..name="李四"
..age=30
..printInfo();
Dart 面共享对象的三大特性:封装,继承,多态
/*
Dart中的类的继承:
1、子类使用extends关键词来继承父类
2、子类会继承父类里面可见的属性和方法但是不会继承构造函数
3、子类能复写父类的方法 getter和setter
*/
class Person {
String name='张三';
num age=20;
void printInfo(){
print("${this.name}---${this.age}");
}
}
class Web extends Person{
}
main(){
Web w=new Web();
print(w.name);
W.printInfo();
}
//super关键词的使用,子类调用父类的方法可用super
Class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo(){
print("${this.name}---${this.age}");
}
}
class Web extends Person{
}{//实例化子类给父类构造函数传参
String sex;
Web(String name,num age):super(name,age){
this.sex = sex;
}
run(){
print("${this.name}---${this.age}---${this.sex}");
}
}
main(){
/*
Person p=new Person('李四',20);
p.printInfo();
Person p1=new Person('张三',20);
p1.printInfo();
*/
Web w=new Web('张三', 12,'男');
//w.printInfo();
w.run;
}
//子类里覆写父类的方法
Class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo(){
print("${this.name}---${this.age}");
}
work(){
print("${this.name}在工作");
}
}
class Web extends Person{
Web(String name,num age):super(name,age);
run(){
print('run');
}
//覆写父类的方法
//覆写的标志,可写可不写,但建议写上
void printInfo(){
print("姓名:${this.name}---年龄:${this.age}");
}
work ( ) {
print("${this.name}的工作是写代码");
}
}
Dart 抽象类
/*
Dart中抽象类:Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
1、抽象类通过abstract 关键字来定义
2、Dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法。
3、如果子类继承抽象类必须得实现里面的抽象方法
4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
5、抽象类不能被实例化,只有继承它的子类可以
extends抽象类 和 implements的区别:
1、如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类
2、如果只是把抽象类当做标准的话我们就用implements实现抽象类
*/
abstract class Animal{
eat();//抽象方法
run();//抽象方法
printInfo(){
print('我是一个抽象类里面的普通方法');
}
}
class Dog extends Animal{
eat(){
print('小狗在吃骨头');
}
run(){
print('小狗在跑');
}
}
Dart 多态
/*
Datr中的多态:
允许将子类类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行效果。
子类的实例赋值给父类的引用。
多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。
*/
abstract class Animal{
eat();//抽象方法
printInfo(){
print('我是一个抽象类里面的普通方法');
}
}
class Dog extends Animal{
eat(){
print('小狗在吃骨头');
}
}
class Cat extends Animal{
eat(){
// TODO: implement eat
print('小猫在吃老鼠');
}
}
main(){
Dog d = new Dog();
d.eat();
Cat c =new Cat();
c.eat();
}
Dart 接口
/*
和Java一样,dart也有接口,但是和Java还是有区别的。
首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
同样使用implements关键字进行实现。
但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。
而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
建议使用抽象类定义接口。
*/
//定义一个DB库 支持 mysql mssql mongodb
//mysql mssql mongodb三个类里面都有同样的方法
abstract class Db{ //当做接口 接口:就是约定、规范
String uri; // 数据库的连接地址
add();
save();
delete();
}
class Mysql implements Db{
String uri;
add(){
// TODO: implement add
return null;
}
delete(){
// TODO: implement delete
return null;
}
save(){
// TODO: implement delete
return null;
}
}
class MsSql implements Db{
String uri;
add(){
// TODO: implement add
return null;
}
delete(){
// TODO: implement delete
return null;
}
save(){
// TODO: implement delete
return null;
}
}
Dart 一个类实现多个接口
abstract class A{
String name;
printA();
}
abstract class B{
printB();
}
class C implements A,B{
String name;
printA(){
// TODO: implement printA
return null;
}
printB(){
// TODO: implement printA
return null;
}
}
Dart mixins
/*
mixins的中文意思是混入,就是在类中混入其他功能。
在Dart中可以使用mixins实现类似多继承的功能
因为mixins使用的条件,随着Dart版本一直在变,这里讲的是Dart2.x中使用mixins的条件:
1、作为mixins的类只能继承自0bject,不能继承其他类
2、作为mixins的类不能有构造函数
3、一个类可以mixins多个mixins类
4、mixins绝不是继承,也不是接口,而是一种全新的特性
5、mixins的类型就是其超类的子类型
*/
class A {
void printA(){
print("A");
}
}
class B {
void printB(){
print("B");
}
}
class C with A,B{
}
void main(){
var c = new C();
c.printA();
c,printB();
}
Dart 泛型
//通俗理解:泛型就是解决类接口方法的复用性、以及对不特定数据类型的支持(类型校验)
/*泛型方法
不指定类型放弃了类型检查。我们现在想实现的是传入什么,返回什么,比如:传入Number 类型必须返回number
*/
T getData<T>(T value){
return value;
}
void main(){
// print(getData(21));
// print(getData('xxx'));
getData<String>('你好');
getData<int>(12);
}
/*
泛型类
*/
/*List list = new List<String>.filled(2,"");
list[0]="张三1";
list[1]="李四";
print(list);
List list2 = new List<int>.filled(2,0);
list2[0]·=·12;
list2[1]·=·13;
print(list2);
*/
class MyList<T>{
List list = <T>[];
void add(T value){
this.list.add(value);
}
List getList(){
return list;
}
}
main() {
MyList 11=new MyList();
11.add("张三");
11.add(12); //不指定,就可以添加任意类型的数据
11.add(true);
print(li.getList();)
MyList 12 = new MyList<String>(); //指定了,就只能添加String类型的数据
12.add("张三");
//12.add(12); 错误的写法
print(12.getList());
}
/*
Dart中的泛型接口:
实现数据缓存的功能:有文件缓存、和内存缓存。内存缓存和文件缓存按照接口约束实现。
1、定义一个泛型接口约束实现它的子类必须有getByKey(key)和setByKey(key,value)
2、要求setByKey的时候的value的类型和实例化子类的时候指定的类型一致
*/
abstract class Cache<T>[
getByKey(String key);
void setByKey(String key,T value);
}
class FlieCache<T> implements Cache<T>{
getByKey(String key){
// TODO: implement getByKey
return null;
}
void setByKey(String key,T value){
print("我是文件缓存 把key=$[key} value=${value}的数据写入到了文件中");
}
}
class MemoryCache<T> implements Cache<T>{
getByKey(String key){
return null;
}
void setByKey(String key, T value){
print("我是内存缓存 把key=${key} value=${value}的数据写入到了内存中");
}
}
void main(){
MemoryCache m=new MemoryCache<String>;();
m.setByKey('index','首页数据');
MemoryCache m=new MemoryCache<Map>();
m.setByKey('index',{"name":"张三","age":20});
}
#Dart 自定义库,系统库,第三方库
/*
在Dart中,库的使用时通过import关键字引入的。
library指令可以创建一个库,每个Dart文件都是一个库,即使没有使用library指令来指定。
Dart中的库主要有三种:
1、我们自定义的库
import 'lib/xxx.dart';
2、系统内置库
import 'dart:math';
import 'dart:io';
import 'dart:convert';
async和await
这两个关键字的使用只需要记住两点:
只有async方法才能使用await关键字调用方法
如果调用别的async方法必须使用await关键字
async是让方法变成异步。
await是等待异步方法执行完成。
3、Pub包管理系统中的库
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、看文档引入库使用
*/
/*
部分导入
如果只需要导入库的一部分,有两种模式:
模式一:只导入需要的部分,使用show关键字,如下例子所示:
import 'package:lib1/lib1.dart'show foo;
模式二:隐藏不需要的部分,使用hide关键字,如下例子所示:
import 'package:lib2/lib2.dart'hide foo;
*/
/*
延迟加载
也称为懒加载,可以在需要的时候再进行加载。
懒加载的最大好处是可以减少APP的启动时间。
懒加载使用deferred as关键字来指定,如下例子所示:
import 'package:deferred/hello.dart'deferred as hello;
当需要使用的时候,需要使用loadLibrary()方法来加载:
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
*/
Dart Null safety
/*
Null safety翻译成中文的意思是空安全。
null safety可以帮助开发者避免一些日常开发中很难被发现的错误,并且额外的好处是可以改善性能。
Flutter2.2.0(2021年5月19日发布)之后的版本都要求使用null·safety。]
?可空类型
//int a=123;//非空的int类型
// a=null; //A value of type 'Null' can't be assigned to a variable of type ' int'
// String username="张三";/非空的String类型
// username=null; //A value of type 'Null' can't be assigned to a variable of type'string'
String? username="张三";//String?表示username是一个可空类型
username=null;
print(username)
// List<String> 11=["张三","李四","王五"];
// 11=null; //A value of type 'Null' can't be assigned to a variable of type'List<String
List<String>? 11=["张三","李四","王五"];
11=null;
!类型断言
String ? str= " this is str
str=null;
print(str!.length);//类型断言:如果str不等于null会打印str的长度,如果等于nu11会抛出异常
*/
#Dart late关键词:主要用于延迟初始化
class Person {
late String name;
late int age;
void setName(String name,int age){
this.name=name;
this.age=age;
}
String getName(){
return"${this.name}---${this.age}";
}
}
Dart required关键词
/*
required关键词:
最开始 @required 是注解
现在它已经作为内置修饰符。
主要用于允许根据需要标记任何命名参数(函数或类),使得它们不为空。因为可选参数中必须有个require
*/
//表示name和age是必须传入的命名参数
cLass Person {
String name;
int age;
Person(required this.name,required this.age});//表示 name 和age 必须传入
String getName(){
return"${this.name}---${this.age}";
}
}
void main(args){
Person p=new Person(
name:"张三",
age:20
);
print(p.getName());
}
//表示name可以传入也可以不传入,age必须传入
cLass Person {
String? name; //可空属性
int age;
Person(this.name,required this.age});//表示 name 和age 必须传入
String getName(){
return"${this.name}---${this.age}";
}
}
void main(args){
Person p=new Person(
name:"张三",
age:20
);
print(p.getName());
}
Dart 性能优化之常量
Dart 常量:final 和 const修饰符
const 声明的常量是在编译时确定的,永远不会改变
final 声明的常量允许声明后再赋值,赋值后不可改变,final声明的变量是在运行时确定的
final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化
//const常量
const PI=3.14;
//PI=3.14159;//const定义的常量没法改变
print(PI);
// final 常量
final PI=3.14;
print(PI);
//final和const区别:final可以开始不赋值 只能赋一次
final a;
a=13;
// a=14;
print(a);
final d=new DateTime.now();
Dart:core库中的identical函数的用法介绍
/*
用法:
bool identical(
Object? a,
Object? b
)
检查两个引用是否指向同一个对象。
*/
void main() {
var o1 = new Object();
var o2=new Object();
print(identical(o1,o2));//false o1和o2不共用一个存储空间
print(identical(o1,o1));//true o1和o1共用一个存储空间
//表示实例化常量构造函数
//o1 和 o2 共享了存储空间
var ol=const object();
var 02=const Object();
print(identical(o1,02));//false
print(identical(o1,o1));//true
//发现:const关键词在多个地方创建相同的对象的时候,内存中只保留了一个对象
print(identical([2],[2]));//false
==
var a=[2];
var b=[2];
print(identical(a,b));//false
print(identical(const [2],const [2]));//true
==
const a=[2];
const b=[2];
print(identical(a,b));//true
}
/*常量构造函数
常量构造函数总结如下几点:
1、常量构造函数需以const关键字修饰
2、const构造函数必须用于成员变量都是final的类
3、如果实例化时不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实
4、实例化常量构造函数的时候,多个地方创建这个对象,如果传入的值相同,只会保留一个对
5、Flutter中const修饰不仅仅是节省组件构建时的内存开销,Flutter在需要重新构建组
*/
//常量构造函数
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);
identical(c1,c2) //flase
var c3=const Container(width: 100, height: 100);
var c4=const Container(width: 100, height: 100);
print(identical(c3,c4));//true