Dart在1.0的时候是弱类型
Dart在2.0的时候是强类型
闭包有什么用?
变量类型
- var 是一个可选类型,dart会自动推断它的数据类型,并不存储值,它存值的对象的引用;
- dynamic 实际运行的是一个Object,他是运行期的,编译器不会对对象检查
- Object 在编译器会对对象检查
变量默认值
- 没有初始化的变量自动获取一个默认值为null
- 一切皆对象,对象的默认值为null
变量-final和const
- 声明的类型可省略
- 初始化后不能再赋值
- 不能和var同时使用
// const和final变量 对象声明时候,类型可以省略
// 值声明过了,值不可以修改
const String str = "";
const str1 = "1";
final str2 = "2";
const与final区别
- static const:表示静态常量
- const与final区别:const在编译期间要确定值,final在运行时确定值
- const定义的构造函数的类的成员变量需要用final修饰
// 因为const的构造函数需要传递value const是在编译器的值,final在运行时确定值
class Man{
final value;
const Man(this.value);
}
const a = 1;
const b = a;
final c = 10;
const d = c; // 不可以这么做,因为final是运行时赋值,const编译时赋值
String
- Dart 字符串是 UTF-16 编码的字符序列,可以使用单引号或者双引号来创建字符串
- 可以使用三个单引号或者双引号创建多行字符串对象
- 可以使用 r 前缀创建”原始raw”字符串 这样转义符号就无法使用
- 可以在字符串中使用表达式: ${expression},如果表达式是一个标识符,可以省略 {},如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串。
String s1 = 'hello' 'word';
String s2 = "hello" "word" + "000";
String s3 = '''
hello
word
000
''';
String s4 = r'''
hello
word\n
000
''';
print(s1);
print(s2);
print(s3);
print(s4);
--------------------------------------------------------
helloword
helloword000
hello
word
000
hello
word\n
000
函数
匿名函数
// 匿名无参函数
var fun1 = () {
print(111);
};
var fun2 = () => print(222);
// 匿名有参
var fun3 = (val) => print(val);
fun1();
fun2();
fun3("hello");
可选位置参数函数
可选命名参数
// 普通函数
fun1(1, 1, 1);
fun2(1);
fun3(1,b: 5,c: 2);
fun1(a, b, c) => print("a=$a b=$b c=$c");
// 可选位置参数,用[] 表示,参数要按着位置写先写b再写c
fun2(a, [b = 1, c]) => print("a=$a b=$b c=$c");
// 可选命名参数,可以直接写b =
fun3(a, {b = 5, c}) => print("a=$a b=$b c=$c");
--------------------------------------------------------
a=1 b=1 c=1
a=1 b=1 c=null
a=1 b=5 c=2
闭包
定义 一个函数内部的函数,不严格的说相当于java的内部类或者匿名内部类。再简单点说-
就是函数套函数。
函数签名
是方法名称和参数类型,叫做函数签名。
?. 相当于不为空则显示点后方法,为空显示null
String str = "xxx";
str !=null?str.length:null;
如果str不是null 则显示长度,是null 就显示null
等同于 str?.length 相当于不为空则显示长度,为空显示null
?? 相当于为空则赋值=号后的不为空则是本身
String str;
str == null?"xxx":str;
str ??="xxx";
~/ 除法取整
print(1~/2);
print(2~/2);
print(3~/2);
print(4~/2);
--------------------------------------------------------
0
1
1
2
循环
List list = [1,"a",2,"t",true];
list.forEach((val)=>print("这里是循环$val"));
for(var val in list){
print(val);
}
异常
- Error异常:大部分是DartVM的异常例如OutOfmemory
- Exception异常 :大部分是需要程序员自己解决的异常
- 自定义异常
构造函数
- 只能有一个非命名构造函数,也就是类名() 就是非命名构造函数
// 只能有一个非命名构造函数 , 下面3个只能存在一个
Man();// 非命名构造函数
Man(this.name,this.age); // 非命名构造函数
Man(String name,int age){
this.name = name;
this.age = age;
}
常量构造函数
常量构造函数是放在常量池中,相同的构造函数即使是new也是同一个构造函数
重定向构造函数
直接重定向函数,是命名构造函数重定向到非命名构造函数,或者子类构造函数继承父类,然后进行重定向父类的某个构造函数,使用:来表示重定向
class Man {
String name;
int age;
// 只能有一个非命名构造函数
// Man();// 非命名构造函数
Man(this.name, this.age); // 非命名构造函数
// Man(String name,int age){
// this.name = name;
// this.age = age;
// }
// 重定向构造函数
Man.setZSInfo(name, age) : this("张三", 16);
Man.setZSInfo1() : this("张三", 16);
}
class Person {
int age;
String name;
Person.setData(this.name, this.age);
@override
String toString() {
return 'Person{age: $age, name: $name}';
}
}
class SubPerson extends Person {
int age;
// 重定向构造函数,子类重定向父类的setData函数,使用:来重定向
SubPerson.setData(String name, int age) : super.setData(name, age);
}
单例
main() {
var singleTong = SingleTong();
var singleTong2 = SingleTong();
print(singleTong == singleTong2); // true
}
// 饿汉式
class SingleTong {
// 定义私有命名构造函数,_表示私有,命名给省略了
// 因为是_私有,在其他类中无法调用这个命名构造
SingleTong._();
// 静态的对象 私有的 ,对象是上面的构造函数获得
static final SingleTong _singleTong = SingleTong._();
// 工厂函数的关键字,通过代码决定返回实例,从缓存中获取实例,也是调用返回实例的方法
factory SingleTong() => _singleTong;
}
工厂方法 通过实现 继承 abstract抽象类
// 构建工厂 抽象类 俱乐部
abstract class Club {
Club.extendsClub();
factory Club(type) {
switch (type) {
case "sky":
return SkyClub();
case "water":
return WaterClub();
case "normal":
return NormalClub();
}
}
getMsg();
}
class SkyClub extends Club {
// 如果是继承,因为factory Club 这个非命名构造函数占用,
// 所以重定向到命名构造函数
SkyClub() : super.extendsClub();
@override
getMsg() {
return "天上人间msg";
}
}
class WaterClub implements Club {
@override
getMsg() {
return "水世界msg";
}
}
class NormalClub implements Club {
@override
getMsg() {
return "Normalmsg";
}
}
Mixin多继承 多个类功能的合并
如下图,交通工具是个父类,动力、安全系数、动力来源,是抽象父类,自行车,摩托车,汽车,可以继承交通,也可以继承动力安全,来进行多继承,把所有的功能进行合并。
父类有个call方法,子类可以直接使用
使用mixin 关键字后,后面继承多个类,如果使用方法在继承的多个类中都存在,则会使用with最后一个类的方法
car("子类直接使用父类的方法,只有call");
}
// 抽象 交通类
abstract class Transportation {
call(str)=>{print(str)};
getInfo();
}
class A {
showMsg() {
print("a");
}
}
class B {
showMsg() {
print("b");
}
}
class C {
showMsg() {
print("c");
}
}
class AB extends A with B,C{
@override
showMsg() {
return super.showMsg();
}
}
AB().showMsg();
----------------------------------------
打印的是c with 后的最后一个类
导包
如果有多个类,可以只导入一个类,然后让这个类把剩下的类都引入,之后导入的这个类,就能访问所有的方法
part of 'libs.dart';
class A {
a() {}
}
----------------------------------
part of 'libs.dart';
class B {
b() {}
}
----------------------------------
part 'a.dart';
part 'b.dart';
class Libs{
showLib(){
print('libs');
}
}
// 引入libs类,可以直接方法a,b类的方法和libs的方法
import 'package:flutter_nd_study/utils/libs.dart';
main(){
Libs().showLib();
A().a();
B().b();
}
as 关键字,可以重命名导入的类名,然后使用
import 'utils/c.dart' as newC;
newC.C().c();
show 关键字,只有导入的类中 show的子类能显示别的不能
part of 'libs.dart';
class D {
d() {}
}
class DD {
dd() {}
}
class DDD {
ddd() {}
}
import 'utils/d.dart' show DD;
只能调用DD类
import 'utils/d.dart' hide DD;
隐藏DD类
import 'utils/d.dart' deferred as DD;
延迟加载dd
异步
- 并发:系统管理多个IO的切换教给CPU来处理
- 并行:多核CPU在同一时间执行多个任务
协程
执行到async表示进入了一个协程,会同步执行async代码快。async本质也是函数,并有自己的上下文环境。当执行到await表示有任务需要等待。CPU就去调度其他IO。过段时间就会轮询,看是否有协程完成了,完成后就继续执行。