flutter学习笔记-dart语言基础

flutter学习笔记-dart语言基础

整理自:用flutter快速构建原生应用

2.3 dart内的内置类型

2.3.1数值类型

int表示整型数据/double表示双精度浮点数,可用64位表示的带小数的数值。
整数数字可以赋值给浮点类型,反之不行。
数值类型的属性:

int a=9;
int b=0XA1;
double d=1.4e2;科学计数法必须声明为double类型
//int和double的属性
int.runtimeType获取运行时类型
int.isFinite//是否为有限值
int.isInfinite//是否为无限值
int.isNaN是否为非数值
int.isNegative是否为负数
int.sign获取是值的符号 返回1代表是整数 -1代表负数 0代表值为0
int.bitLength 获取当前int类型数值需要的最小位数  int独有属性
int.isEven/int.isOdd 是否为偶数/奇数 int独有属性

数值类型的方法:

num.abs() 获取绝对值
num.ceil()向上取整
num.ceilToDouble()向上取整且转换为浮点数
num.floor()向下取整
num.floorToDouble()向下取整且转换为浮点数
num.round()四舍五入取整
num.roundToDouble()四舍五入取整且转换为浮点数
num.truncate()//丢弃数值的小数部分 返回整数
num.truncateToDouble()//丢弃数值的小数部分 返回整数并转为浮点数
num.clamp(1,10)返回指定范围内离当前数值最近的数,如果num在返回内返回num
num.compareTo(1)将当前数值与传入的值进行比较,如果大于参数返回1 如果小于参数返回-1,否则为0
num.remainder(5)//取除以5得到的余数
num.toDouble()//转换为浮点
num.toInt(5)//转换为整数
num.toString()转换为字符串
//int独有的方法
int.gcd(7) 获取当前数和参数的最大公约数
int.modInverse(6)//求模逆运算
int.modPow(3,5)先进行逆运算再求模运算 //int进行3次方后除以5取余数


2.3.2字符串类型

单双引号表示字符串类型,${}表示字符串插值。三对单(双)引号可以表示多行字符串。
反斜杠表示字符串转义。字符串引号前加上r代表原始字符串。
字符串创建方式:

var str='zifuchuan' //字面量表示法
var str1=String.fromCharCode(97)//字符码97对应字符a 
var str2=String.fromCharCodes([97,98,99])//abc

字符串的属性:

str.codeUnits//获取字符串的字符码集合
str.isEmpty//s是否是空字符串
str.isNotEmpty//s是否是非空字符串
str.length//获取字符串长度
str.runtimeType获取字符串运行时类型

字符串方法:

'hello'.codeUnitAt(0)//104通过下标获取字符串中某个字符的字符码
'hello'.compareTo('a') 104>97值是0 ‘逐个字符进行字符串字符码的比较1,-1,0
'hello'.contains('h')是否包含
'hello'.endsWidth('h')是否以h结尾
'hello'.startsWidth('he')是否以h开头
'hello'.indexOf('he')获取匹配位置
'hello'.lastIndexOf('he')获取逆向匹配位置
'hello'.padLeft(10,'h')在左边进行字符串位数补齐
'hello'.padRight(10,'!')在右边进行字符串位数补齐
'hello'.replaceAll('e','h')替换指定字符
'hello'.reokaceRange(0,3,'h')将指定范围内的字符串进行替换
'hello'.split('e')将字符串分割为数组
'hello'.subString(1,3)字符串截取
'hello'.toLowerCase()/ 'hello'.toUpperCase()全部转大/小写
'hello'.trim()去掉首位空格
'hello'.trimLeft()去掉首空格
'hello'.trimRight()去掉尾空格
'hello'[1]//e获取字符串集合中某个元素


2.3.4列表数组类型

列表具体的数据类型由其中的元素类型决定。
列表变量声明方式:

List <int> list=[1,2,3,4];//如果明确元素类型,则只能存放这种类型数据
List <dynamic> list=[1,2,3,'4'];//动态类型列表,则只能存放不同类型数据
var list=[1,2,3,4];  用var进行声明,可以以自动类型推断
var list2=new List(5)//长度为5 默认值是null填充
var list3=List.filled(3,1)//[1,1,1]//创建指定长度,指定默认值的列表
var list4=List.from(list3) 通过另一个集合列表类型的数据来创建列表
//列表的属性
[1,3,5,7].first//第一个元素
[1,3,5,7].last//最后一个元素
[1,3,5,7].length//列表长度

列表方法:

var l=[];
l.add(1)//增加单个元素
l.addAll([2,3])//增加一组元素
l.asMap()//将列表映射为下标为key的字典对象{0:1,1:2,2:3}
l.fillRange(0,2,'a')//覆盖列表中某个范围的元素
l.getRange(0,2)//获取列表中某个范围的元素
l.indexOf('a')//顺序获取列表中某个元素的下标,没有返回-1
l.lastIndexOf('a')//倒序获取列表中某个元素的下标,没有返回-1
l.insert(0,'a')//指定位置插入一个元素
l.insertAll(0,['a'])//指定位置插入一组元素
l.remove('a')//删除指定的第一个元素
l.removeAt(1)//删除指定下标元素
l.removeRange(0,2)//删除指定下标区间元素
l.replaceRange(0,2,[1,2,3,4])//替换指定区间元素为集合参数中的元素
l.sublist(0,3)//返回由截取的元素组成的列表
l.contains(2)//是否包含指定元素
l.join('*')//拼接为字符串
l.toString()//列表转为字符串 [1,2,3,4]
l.clear()清空列表


2.3.5Map对象类型 同js Object

一般情况下,键都是字符串类型,但可以是任意类型的。但是注意,与list一样, 一旦map的类型确定,其键和值的类型就必须遵守。
完整的map类型变量的声明:
Map map2 ={"1":1,"2":2};
map的常用属性和方法:

/**属性**/
{"1":1,"2":2}.isEmpty是否是空对象
{"1":1,"2":2}.isNotEmpty是否是非空
{"1":1,"2":2}.keys 获取所有键
{"1":1,"2":2}.values 获取所有值
{"1":1,"2":2}.length 键值对个数
{"1":1,"2":2}.runtimeType 运行时类型
/**方法**/
{"1":1,"2":2}.addAll({'name':'lucy','age':19})//添加键值对
{"1":1,"2":2}.containsKey('name')//是否包含某个key
{"1":1,"2":2}.containsValue('lucy')//是否包含某个value
{"1":1,"2":2}.remove('name')//删除某个键值对
{"1":1,"2":2}.toString()//转换为字符串
{"1":1,"2":2}.clear()//清空字符串


2.4 dart运算符

dart运算符包含算数运算符/比较运算符/类型运算符/复合运算符/逻辑运算符/位运算符和条件运算符等。

2.4.1算数运算符

dart中,并非只有数值才支持加运算,字符串/列表/map等数据类型也支持相加运算。

print(2+1)//加法运算符
print(2-1)//减法运算符
print(2*4)//8 乘法运算符
print(10/2)//5.0 除法运算符必定返回浮点数
print(9~/2);//4 整除运算,
print(9%2)//1 取模运算符
//另外dart支持自增自减运算符。
a++ 与++a的区别是前者除了将变量加1外,还会将计算后变量a的最新值返回。


2.4.2比较运算符

==相等 !=不等 >大于 <小于 >=大于等于 <=小于等于

2.4.3类型运算符

dart中的类型运算符有3种:as/is/is!。
as 告诉dart将当前数据当作某个类型的数据处理,并不会真正进行数据类型修改。
is 判断数据是否属于某个类型 返回bool类型
is!判断数据是否不属于某个类型 返回bool类型

2.4.4复合运算符

总是一种运算符与赋值运算符的组合。常用的复合运算符:
+=复合加运算符 ==复合加运算符 *=复合乘运算符 /=复合除运算符 ~/=复合整除运算符 %=复合求余运算符
<<=复合左移运算符 >>=复合右移运算符 &=复合按位运算符 ^=复合按位异或运算符 |=复合或运算符
c??=0 //与c=c??0;意义一样,若c结果是null,给c赋值为0.

2.4.5逻辑运算符

逻辑运算符是针对布尔值进行运算的运算符。逻辑运算符的操作数只能是true或false
!逻辑非运算符 ||逻辑或运算符 &&逻辑与运算符

2.4.6位运算符

位运算符是针对二进制位进行操作的运算符。
&按位与运算 将两个操作数的每一个二进制位分别进行与运算,同样位置都是1,则结果是1.
|按位或运算 将两个操作数的每一个二进制位分别进行与运算,同样位置不都是0,则结果是1.
^按位或运算 将两个操作数的每一个二进制位分别进行异或运算,同样位置相同,则结果是0,否则为1.
~按位非运算 只有一个操作数,对操作数的每一个二进制位进行取反。
<<按位左移运算 对操作数二进制位向左移动指定位数(符号右侧的数)。
>>按位右移运算 对操作数二进制位向右移动指定位数(符号右侧的数)。

2.4.7条件运算符

?:三元运算符 同js
??空条件运算符 若第一个操作数为null,则运算后的值为第二个操作数的值。
c??=0 //与c=c??0;意义一样,若c结果是null,给c赋值为0.

2.4.8级联运算符

级联运算符是对对象执行一组操作,操作可以是对对象赋值,也可以是对对象方法的调用。如:
var p=People()..name="会笑的眼睛"..age=26;

2.4.9点运算符

用来对对象的属性与方法进行操作,对null值用点运算符会抛出异常,而 ?.条件成员访问运算符 c?.a 如果所调用的对象是非null值,就会正常访问,否则发返回null,但不报错。

2.5 dart中的流程控制语句


2.5.1条件分支语句

if-else 可以多级条件判断

2.5.2循环分支语句

while循环 do-while循环 后者总会先执行一次
for循环 for-in 用于对集合类型对象遍历,也被称为迭代语句

2.5.3中断语句

break直接跳出当前层的循环 后续不会执行
continue跳过本次循环后,还会进行循环条件的判断,如果条件依然满足,就会继续执行循环。

2.5.4多分支选择语句

switch-case(default)

2.5.5异常处理

要抛出的异常可以是任意类型的对象。通过定义异常类来封装异常,异常中有原因/类型/错误码等信息。
在dart中提供了try-on(-catch)-(finally)来捕获运行时异常,可以在捕获后选择进行处理/忽略/继续异常抛出。
要继续进行异常抛出,可以使用rethrow关键字即可。
finnally块常用来执行数据清理相关操作。如:

main(){
    var a=-10;
    if(a<0){
        throw "输入有误";
  }on int{
    print('捕获了整数类型的异常')
  }on string catch(exp,st){}
    print('捕获了字符串类型的异常:$exp\n$st');
    rethrow;//继续抛出异常
  }finally{
    print('异常处理结束');
    print('程序完成')
}


3.1函数使用

3.1.3 名称可选参数和位置可选参数的函数

//定义名称可选参数
myFun({string name,int age}){
  if(name!=null){
  print('名字是:$name')
  if(age!=null){
  print('年龄是:$age')
//定义位置可选参数
myFun(string name,[int age]){
  if(name!=null){
  print('名字是:$name')
  if(age!=null){
  print('年龄是:$age')
//使用名称可选参数
myFun('会笑的眼睛');


3.1.4可选参数的默认值

如果调用者没传入某个参数,则获取到的是null.

myDun({Strung name="名称可选参数默认值",int age=1}){}
myDun([Strung name="位置可选参数默认值",int age=1]){}


3.1.5匿名函数

可以直接赋值给变量,页可以通过匿名函数创建自执行的函数。
自治性函数更大的作用会生成一个新的内部作用域。

3.1.6词法作用域

在dart中,大括号会生成作用域,在作用域内声明或定义的变量,出了作用域就被销毁并且无法使用。
外层作用域中的变量是可以内层使用的,但是优先使用内层作用域中的同名变量。

3.2dart中的类

构造方法有自动匹配赋值的特性,且不会被继承。
命名构造方法通常用来快速创建标准对象。
在方法中可以通过this关键字获取对象的属性信息,也可以调用其他方法。方法也需要通过点语法来进行调用。
类的Setters和Getters方法常用来设置获取对象属性,或者定义附加属性(不是描述对象的原始数据,而是可以通过计算的来的属性。)

class Teacher{//description就是附加属性
  String get description{return xx};
  set description(string value){}
}


3.2.3 抽象类与抽象方法 (接口)

抽象类中可以定义抽象方法,抽象方法是只有定义却没有实现的方法。//可以理解为不同类之间的协议/接口。
抽象类不能被实例化,只能通过实现这个接口的类或者继承它的子类来实例化对象。

abstract class TeacherInterface{//定义
  void teaching();
//实现接口抽象
class Teacher implements TeacherInterface,manInterface{//一个类可实现多个接口
    void teaching(){print('我实现了抽象方法')}
}


3.2.4 继承

在dart中,通过使用extends关键字进行类的继承。
构造方法不会被继承,在子类中使用super关键字来调用父类的方法,包含构造方法。
子类可以重写父类的方法,并且在重载时可以调用父类的对应方法。其中@override关键字可以省略

3.2.5运算符重载

dart运算符的运算本质是方法的调用,所以,我们可以为自定义的类添加运算符方法。
支持重载的运算符:< > [] []= <= >= >> + | / ^ ~/ & % ~
@override

@override  //重载此方法 可以避免调用到未实现的方法时异常问题,不过要尽量少用
void noSuchMethod(Invocation invocation){
print('调用了未实现的方法')
}


3.2.7枚举类型

枚举是描述有限个数的数据集合,enum关键字定义枚举,它也有从0开始的下标。页可以和分支语句结合使用。

3.2.8 mixin混合

能够被混合的类被成为Mixin类,mixin类中不能实现构造方法,否则不能够被其他类混合,
使用with关键字,用逗号分隔可以支持多混合。
对于继承和混合一起使用的场景中,相同方法实现优先级规则:
1.当前类中的方法优先级最高,
2.其他情况,看类声明时,谁靠后谁优先级高。从左到右依次增高。

3.2.9类的属性(静态属性)和类的方法(静态方法)

静态属性通常用来存放固定的且在类的所有实例中共享的属性。
静态方法通常用来提供一些静态的计算功能。

3.3 泛型(通用类型)

T标识符进行类型占位,其实际类型会在运行时确定。
函数名或者类名后的尖括号中用来指定泛型的类型,这个类型可以在函数的返回值/参数类型/甚至参数类型的泛型以及函数体中使用。

3.4 异步编程技术

在dart中,可以使用async和await关键字编写异步编程,也可以使用Future对象相关方法来处理异步任务。

3.4.1 async await

需要被异步执行的函数需要使用async关键字修饰,函数内需要进行之后处理的语句使用await关键字修饰,只有在async函数中才能使用await关键字。

main(){
    getData(renderUI);
    print('继续执行。。。')
renderUI(){