flutter零基础教程: Dart 3.5语法 flutter3.24 2024年8月27日更新
flutter零基础教程: Dart 3.5语法 flutter3.24 2024年8月27日更新
https://www.bilibili.com/video/BV1RZ421p7BL
7 14
2024-8
edu.51cto.com/course/36476.html
P1 课程大纲介绍
P2 002课程使用方法介绍和笔记使用
P3 003_mac系统查看笔记软件的安装方法和…..
P4 004黑苹果系统的安装
P5第二章 mac装机篇:001国内镜像homebre..
P6 002github443报错homebrew安装前报错Fa..
P7 003安装flutter和dart sdk macos 14和老版...
P8 004mac android studiio安装和配置flutter d.
P9 005自定义代码段建立和导出导入(选学)
P10 006_xcode和ios模拟器安装
windows和 mac编译器ctrl 和 Alt是颠倒的
P11 007_ios模拟器启动错误和运行时渲染错...
P12 008a_安卓模拟器学习阶段不用安装的
P13 008android studio安装安卓模拟器
P14 009_mac下 android studio启动报错解决.
P15 010cocoa_pod安装错误和flutter项目启动
P16第三章windows装机篇:01_windows下...
P17_02_android studio下载安装
P18 03_windowsFandroid studio安装必选插件
P19 04_配置windows的android studio和系统..
P20第四章dart语法部分000B站用户笔记查看.
设置独立模拟器 cmd+,搜索launch,去掉这个勾,重启 android studio 可以独立运行模拟器
P21 001视频与笔记代码对应顺序代码第一次...1
P22 001a快捷键1
P23 001b快捷键2定位抽象类的子类
P24 001c快捷键3
P25 01在android studio下新建第一个文件...
P26 02类型字面量整形字符串嵌套自定义快捷键1
P27 03常量const和final变量命名规则
P28 04var自动推断类型
P29 005int和double的相互转换和浮点型底层...1
P30 006数学运算符
不支持驼峰 变下划线 文件名.dart
toInt()
P31 007动态类型dynamic和函数汇编中函...
dynamic 动态类型和dart中的函数
dart中如果使用dynamic类型,定义,那么在编译期间不进行类型检查,而是在运行时候通过赋值自动推断出类型,dynamic可以用来定义变量和 函数的返回类型
dynamic区别于var的是:var不能用作函数返回类型
var al= 100;dynamic a2=100;print(al);print(a2);函数:可以理解为是可以重复执行的代码段,本质上就是汇编里的call指令,功能是调用子程序,函数的参数列表里面存的变量,会在call语句执行之前,先执行push指令操作,把函数的参数压入到栈当中之后执行call,执行完函数以后,会执行一个平栈操作,内平栈或者外平栈,来完成栈平衡,如果在逆向中乱改汇编指令,又不会计算栈平衡,会破坏栈平衡,导致程序崩溃,会执行到调用call指令的下一条指令返回类型 函数名(参数列表)
函数体
return 返回值
一
函数存储在代码段里,函数执行多次也不会重复在内存中写入多个代码段,而只会保存一份
函数里面的参数是局部变量,保存在栈里面,每次参数传递进函数的之前都会把要传递的参数压入到栈中
函数定义的格式://函数参数列表
void show(String str){
A print("show执行str=$str");int add(int a,int b){
return a+b;函数中如果不写返回类型,默认是dynamic类型
这2个等价
//类型提升,可以空的类型,可选类型 String?,通过类型提升,可以变成 String var a= 100;//静态分析,在编译器运行之前,就能推导
P32 007b(重录补充)-静态分析var和动态类...
P33 008函数的返回类型和dynamic
P34 009List列表和add追加方法
List是dart中的数组,他有其他语言中的数组和队列的功能,是可变数组,可以添加,插入,删除,排序,map映射等几十个方法,这里只列举出十几种常用方法
排序reversed以后会产生新的概念:Iterable可以迭代的.其他语言中有迭代器的概念
map0方法执行以后也会产生Iterable迭代操作需要注意的是List的map方法里面的格式出现了匿名函数和箭头函数,这个我们后续会讲解,今天只需要记住这种固定格式就可以了.
map0方法返回的迭代操作不会自己执行,需要遇到toList(
方法才会执行
.add .addAll .insert insertAll remove
removeAt removeLast
isEmpty判断是否为空
/isNotEmpty判断是否不为空
/removeRange,参数1,开始删除的序列,参数2,直到删除到参数2的前一个序列
list.reversed.toList()
P35 010List列表的其他常用方法
P36 011List数组的map和reversed方法Iterable
P37 012箭头函数初次体验
P38 013Function函数类型和匿名函数作为参...
void main() {
// Function(int, int) fn = add;
Add fn = add;
print(fn(1, 2));
}
typedef Add = int Function(int, int);
int add(int a, int b) {
return a + b;
}
P39 014main函数的几种形式终端调用main函…
main 函数的几种形式 终端调用 main 函数并且传参数main0 不写返回类型那么就是 dynamic 类型,运行时候自动推断返回类型void main)无返回类型
int main)返回整形
main(List list)带参数列表,可以给主函数传送参数在终端调用 dart run 指令运行 dart 文件
P40 015加加减减自增自减运算
P41 016for循环while和do while循环
void main() {
List list = [1, 2, 3, 4, 5];
for (var item in list) {
print(item);
}
}
P42 017自定代码段让变量有默认值List下标.
P43 018List.generate生成数组.运算符拆解...
List.generate 生成数组
参数1序号.自动生成的index是每次遍历出来的序号.右边是一个表达式,表达式计算的值用来填充到Lis中1这个例子序号是10.1.234],右边表达式.把序号index2,那么就是(0.2468):
var list3 = List generate((5),findex)=> index2);print(list3);
…运算符拆解并且合并数组
.3个点的作用是拆掉一层1把…后面的数组变成了元素相当于是把1维数组变成了连续排列的一串元素
/例如:[1,2.3]使用…以后 就变成了:1,23一般用来用一个已经存在的数组,放到另一个数组里面
List list1=1-[12.31.456):List list2=[1,2,3):listl=|list2,4,5,6};
11...3个点的作用是拆掉一层0,把…后面的数组变成了元素,相当于是把1维数组变成了连续排列的一串元素
//例如:[1,2,3]使用…以后 就变成了:1,2,3
void main() {
List list = List.generate(10, (index) => index * 2);
print(list);
List arr1 = [1, 2], arr2 = [3, 4];
print([...arr1, ...arr2]);
}
P44 019Set集合
Set没有顺序,不能通过下标访问:
Set不可以重复
void main() {
Set<int> s1 = new Set<int>();
var s2 = Set();
var s3 = Set<int>.from([1, 2]);
s1.add(2);
}
P45 020as类型转换Map键值对的创建初始化
as 类型转换
//Map是键值对,泛型第一个类型是键,key,第二个是值,value,有点像Oc字典,也有点json一
//键值对可以是任何类型
//int String类型
//下面是强制给出Map的类型,那么就不能给其他类型
void main() {
dynamic d1 = 'hello world';
var str = d1 as String;
print(str.length);
var m1 = Map<int, String>();
m1[1] = 'hello';
dynamic m2 = {"name": 'koo', 'no': 88};
m2.addEntries([MapEntry('age', 29)]);
print(m2);
}
P46 021MapEntry键值对String拼接变量和Ma
MapEntry()创建一个键值对,用来组合 Map 的,一般用来组合 map 键值对用
字符串拼接变量,用字符串两边加引号 +$变量名,跟打印一样
.map()方法是遍历 Map 里面的所有键值对,每次遍历把键值分别放到(key,value)中
.map()方法是遍历 Map 里面的所有键值对,每次遍历把键值分别放到(key,value)中箭头函数=> 相当于(return一行代码)
entries.map 返回一个迭代器,可以是任何类型,这样就可以把 Map 转换为其他类型的迭代器,再转为数组List用asMap()方法转换为Map,调用map方法
void main() {
dynamic m2 = {"name": 'koo', 'no': 88};
var m1 = m2.map((key, value) => MapEntry(key, value.toString() + ' diy'));
print(m1);
}
P47 022迭代操作的执行和Map的entries.map.
print 用时 才调用map..
/List 用asMap()方法转换为Map,调用map方法
void main() {
dynamic m2 = {"name": 'koo', 'no': 88};
var m1 = m2.entries.map((e) {
return 'diy ${e.key} + ${e.value}';
});
var list = m1.toList();
var m3 = list.asMap();
print(m3);
}
P48 023List和Map的forEach方法
List.forEach 方法
默认自动生成一个匿名函数
可以手动传入一个单参数的函数名
Map.forEach 方法
默认自动生成一个2个参数的匿名函数
可以手动传入一个2 个参数的函数名
void main() {
dynamic m2 = {"name": 'koo', 'no': 88};
m2.forEach((key, value) {
print('forEach ${key}=${value}');
});
var list = [1, 'str'];
list.forEach((ele) => print(ele));
}
P49 024bool类型双等号不等号和if和else if判断
P50 025is运算符判断变量是否是属干一个类型.(
if(str is String)[]
P51 026List继承自Iterable迭代操作并且使用It...2
Iterable.
P52 027三目运算符问号冒号
P53 028问号可选类型可空类型保存null空Strin...0
//?问号可选类型,可空类型Lint?i1=100-
String.isEmpty '' isNotEmpty
P54 029可空类型叹号强制解包问号双问号运…..3
//因为可选类型不能进行运算,例如判断是否>60,所以用辍制解包,把可选类型变成普通的非空类型强制解包,把可选类型变成非可选类型,例如把String?变成String,把int?变成int但是如果可选类型里面保存的值是null,那么运行报错
//把可选类型当做函数形参
var flag=str??false;
try{}catch(e){}
P55 030数字和String互相类型转换parse和toS...
parse toString
P56 031通过String 的contains判断是否包含字….2
str.contains('abc');
//Iterbale.where只有在匿名函数中返回true的值才会被筛选,返回false不会,被筛选,返回的是Iterable
P57 032-033函数可选参数位置可选参数命名…..
fn(int? a){}
P58 034自执行匿名方法和自执行方法
P59 035汇编角度讲解全局变量和局部变量
P60 036闭包和闭包捕获变量(重录)
65
P61 037类和对象和属性的概念_new_late关键字
late int a;//late关键字告诉编译器,稍后在初始化
P62 038类的构造函数this关键字构造函数简写
P63 039hashCode判断对象和变量和类的命名…..
hashCode判断不同对象和类的命名构造函数hashCode把对象进行哈西运算生成的哈西值
-类的对象的属性相同,但是对象不同,返回的hashCode不同普通的变量不同,但是值相同,那么返回的hashCode想通
p1.hashCode
P64 040类的静态方法和静态成员变量
P65 041setter和getter赋值和读取set get方法
set get
P66 042.import关键字包含其他文件和目录mp4
import关键字可以包含其他文件引入其他文件夹下时,可以在路径里面填写相对路径.
如果是上层路径使用../退回上一层目录
P67 043类的私有成员和私有方法的使用
类的私有成员和私有方法
dart中定义私有成员和属性不是用的private或者protected受保护的关键字,而是用下-划线开头在同一个文件下,_开头的对象的私有方法和私有成员可以被访问不在同一个文件下,import引入进来的不能访问_开头的私有成员使用普通方法访问私有方法和私有成员变量
P68 044类的初始化列表和final属性初始化和...
class Persion{
int id;
Persion(int id):this.id=id;
不能在初始化列表里面执行賦值之外的其他操作,例如打印
}
P69 045级联操作符2个点
级联操作符2个点..
连续2个点..是级联操作符,作用是把一个对象下面的方法或者成员连续使用出来.
级联操作返回的是操作符左边的对象
注意事項:
-第一行的对象结尾不能加分号,最后一个成员或者方法结束再加分号,本质上是一行代码级联操作符右边的表达式不管是赋值还是方法,都返回左边的对象
-一般级联操作,都是换行使用,这样格式看起来清晰(推荐)
P70 046extends继承父类super构造函数
extends 关键字,继承父类,右边是父类,左边是子类,默认情况下,什么都不写,子类拥有父类全部的方法和成员变量,但是必须初始化父类的构造函数
extends 关键字只能继承 1 个父类,如果要继承多个父类,需要使用 implements,后续讲子类可以有自己的属性
子类的构造函数必须把父类的构造函数也初始化了,这里指的初始化是指调用父类构造函数,同时给构造函数參数赋值
不只是dart语言,其他一些语言,调用子类构造函数的时候,也要求调用父类的构造函数例如swift:中super.init()是调用父类的构造函数.super.viewDidLoad()调用父类的viewDidLoad初始化父类构造函数可以在冒号后面的初始化列表里面写 super(参数列表)
void main() {
var s1 = new Student('koo', 100);
}
class Person {
String name;
Person(this.name);
}
class Student extends Person {
int score;
Student(super.name, this.score);
// Student(String name, int score)
// : this.score = score,
// super(name);
}
P71 047override重写
类中 方法复写 @override
P72 048abstract抽象类
P73 049多态
P74 050implements和extends区别
extends是单继承,只能继承1个父类如果父类是抽象类,要求必须重重写抽象方法和抽象属性,普通方法不用重写,extends继承,可以使用super关键字调用父类的普通方法implements在其他语言中叫做 遵守协议,或者继承接口.作用是可以同时继承多个父类implements可以同时继承多个父类,要求实现父类所有方法,不管是不是抽象的,不能使用super.关键字调用父类方法,因为所有方法都会被当做抽象方法1
I
implements在其他语言中叫做 遵守协议,或者继承接口.interface 作用是可以同时继承多个父类implements可以同时继承多个父类,要求实现父类所有方法,不管是不是抽象的,不能使用super.关键字调用父类方法,因为所有方法都会被当做抽象方法
implements 可以继承普通类 抽象类 但必须复写
没有接口这个概念
P75 052泛型方法和runtimeType运行时类型
泛型的作用是减少重复代码,可以用套代码,使用泛型设置参数类型以后,让这套代码重复使用方法的0小括号前面加<>尖括号,里面是类型
显示的在<>尖括号中指定类型,那么后面传入参数也要是这种类型
P76 053泛型在类中的使用构造函数中的泛型…..
泛型可以限制类的参数类型.给类的构造函数传入参数,让泛型识别出指定的类型
P77 054泛型通过extends限制类型
泛型可以通过extends关键字限制泛型的类型是某一个类型或者他的子类 <T exends 某个类型>
void main() {
var s1 = new Student(new Person());
s1.action();
}
mixin Organism {
run();
}
class Person with Organism {
@override
run() {
print('person runing');
}
}
class Student<T extends Person> {
T person;
Student(this.person);
action() {
person.run();
}
}
P78 055泛型接口
dart中没有接口的概念,根据其他语言的概念,勒种只有方法声明,没有方法体的实现,这样的类.dart中的接口可以理解成:只有抽象方法的 abstract class抽象类
P79 056is和as在父类子类中的转化和判断自...
is和as在父类子类中的使用
父类型的对象通过as转换成子类型调用子类方法is判断父类型的对象,如果是子类型,自动转换为子类型,可以调用子类型的方法
Person p1=new Work();
(p1 as work).work();
//通过is 判断类型以后,如果是子类型,那么对象的类型变成子类型,可以调用子类方法
void main() {
var s1 = new Student('koo', 100);
}
class Person {
String name;
Person(this.name);
}
class Student extends Person {
int score;
Student(super.name, this.score);
action(Person p1) {
if (p1 is Worker) {
p1.he();
}
}
}
class Worker extends Person {
Worker(super.name);
he() {}
}
P80 057import导入as前缀解决冲突show和hid...
import导入的时候通过as给导入的库加一个前缀,解决跟其他库的方法重名冲突的问题过导入的时候 show关键字是 部分导入,只暴漏 show关键字后面的方法hide也是部分导入.隐藏hide关键字后面的方法,其他的都暴漏出来
import 'xxx' as x show fn, show;
import 'xxx' as x hide fn, show;
P81 058常量构造函数常量命名构造函数identical1
常量构造函数 需要在构造函数左边加 const,同时,所有成员变量都是final类型.这样赋值一次以后参数就不会改变,或者是static常量命名构造函数.跟常量构造函数一样,左边有const,右边是命名构造函数 类名.方法名+(参数),要求所有成员都是final
void main() {
var p1 = const Person('koo');
var p2 = const Person('koo');
print(p1.hashCode);
print(p2.hashCode);
print(identical(p1, p2));
}
class Person {
final String name;
const Person(this.name);
}
P82 059a_const常量构造函数调用省略和不能..
常量构造函数不能用函数体
调用const的构造函数可以省略const.但是省略const以后,相同成员变量创建的对象存储空间就不一样了,可以简单记忆成const在等号右边可以省略
常量构造函数不能用函数体
/static const可以读取,不属于某一个对象 可以print 但是不能赋值
P83 059b-常量构造函数补充传入参数是变量
P84 060const外层构造函数嵌套内层const构...
类的构造函数是常量构造函数,但是如果调用构造函数的时候传入的值,是可变的,不是常量,那么调用的时候也不能加const如果常量构造函数加了const要求里面传入的参数必须是不可变的,例如是const类型的,如果是类的对象,要求这个对象也是用常量构造函数创建的
P85 061构造函数和子类中的可选参数和命名...
构造函数中的[]和0跟普通函数一样,0可选参数列表和号命名参数列表,里面的参数都是可选类型,或者是有默认值的非可选类型0大括号多了一个required必填项
子类继承父类中的□和量的时候,也要加上括号
P86 062异常Exception错误Error断言assertthr...3
//assert断言,只要括号里面的表达式结果不是true,代码就不会继续执行,除非有try catch assert(true);
//throw()括号里面放上异常,可以抛出异常
void main() {
try {
assert(true);
print(11 ~/ 0);
} on IntegerDivisionByZeroException catch (e) {
print('zero error');
} catch (e) {
print(e);
}
}
P87 063factory工厂构造函数
factory关键字的构造函数要求手动return对象.
跟其他构造函数区别,构造函数本身自动返国对象,不需要在函数体里面手动return 对象
//factory关键字的构造函数要求return对象,但是不会像其他构造函数那样,执行到函数体的时候已经是创建对象
void main() {
var p1 = Person('koo');
var p2 = Person('koo');
print(identical(p1, p2));
}
class Person {
String name;
Person._init(this.name);
factory Person(String name) {
return Person._init(name);
}
}
P88 064factory static单例模式
void main() {
var p1 = Person();
var p2 = Person();
print(identical(p1, p2));
}
class Person {
static final _instance = Person._init();
Person._init();
factory Person() {
return _instance;
}
}
P89 065_01_Future异步基本使用
P90 065_02_Future语法模拟
P91 065_03_Future_then使用
P92 065_04_Future_then 解决嵌套地狱
P93 065_05_Future_value_delayed_whenCo...
P94 066_01_Future作为返回值和泛型
P95 066_02_await_async等待异步结束
P96 067 external关键字普通类中使用抽象方法
extermal天键字翻译以来是外部的意思.在c++中天键字 extemn 可以应用于全局变量,而数๔模板的产明,就是只是各计编译器有这个方法.需要再其他文件中手代定文在dart中的使用如下
这个例子实验external关键字,在普通类中,可以让方法只声明方法名,不实现方法体、于类继承这个方法的时缓,可以重写.也可以不重写extemal使用可以让普通类重的方法信抽拿类abstract那样.写出抽拿方法,就是不实现方法体的方法.但是拿类的抽拿方法子类應承必成重写而普通类的extermal方法,子类继承以后不是必须实现这些externat方法
void main() {}
class Person {
external run();
}
class Student {
@override
run() {}
}
P97 068 库library模块part of export
一个库里面可以有多个模块,一个模块里面可以有多个类.函数
库文件中使用 library创建库
模块一般用一个单独的文件保存,要引入库,就用part"文件名"引入.如下引入'pl.dart 和p2.dart'模块文export是导出库,可以让引用当前库的文件,使用导出的库,例如当前所有import poisonLib的文件,都可以不用包含dartio库就能使用里图约方法要放在part和lbrary之间,export导出文件以后,再使用这个库的文件,就不用再import dart io库了export餐放在part和ibrary之间.export导出文件以后,再使用这个库的文件,就不用再import dart:io库了在模块文件中使用part of 加上库名,代表是属于某一个剛
//export是导出库,可以让引用当前库的文件,使用导出的库,例如当前所有import poisonLib的文件,都可以不用包含dart:io库就能使用里面的方法
//要放在part和library之间,export导出文件以后,再使用这个库的文件,就不用再import dart:io库了
import 'package:demo/my_lib.dart';
void main() {
hello();
}
lib
library my_lib;
export 'dart:io';
part 'module1.dart';
module;
part of my_lib;
hello() {
print('hello');
}
P98 069运算符重载operator
运算符重载关键字是 operator 加一个运算符
右边的0里面是传人的时候
不是所有运算待都能被用户
右边的对象
空加.
void main() {
var p1 = new Person('koo', 18);
var p2 = new Person('koo', 28);
print(p1 > p2);
print(p1 == p2);
}
class Person {
String name;
int age;
Person(this.name, this.age);
bool operator >(Person other) {
return age > other.age;
}
@override
bool operator ==(Object other) {
if (other is Person) {
return name == other.name;
}
return false;
}
}
P99 070linux命令grep查找系统dartsdk的exter.0
poison@poisondeMini internal % cd Nolumes/SN7501T/flutter/bin/cache/dart-sdk/li
源代码
P100 071终端和编译器命令行执行dart和pubd...2
P101 072 enum简单枚举和加强型枚举switch
枚举类型
枚举类型,通常称为枚举成enums,是一种特殊的类,用于表示一组固定数量的常量值。
注意:所有的enums都自动扩展Enum类。它们也是封闭的,意味着它们不能被子类化,实现,混合或以其他方式蓝式实例化。
抽象类和mixin可以显式实现或扩展Enum,但除非它们被enum声明实现或混入,否则没有对象可以实际实现该类或mixin的类型。
声明简单enums要声明简单的枚举类型,请使用enum关键字并列出要枚举的值:dart Copy code enum Color(red,green,blue)
提示:在声明枚带类型时,您还可以使用尾随逼号以帮助防止复制贴贴错误。
声明增强enums Dart还允许enum声明声明具有字段、方法和const构造函数的类,这些类仅限于固定数量的已知常量实例。
要声明增强enum,请遵循与普通类类似的语法,但有一些额外的要求:实例变量必须是final,包括mixin添加的变量。
I所有生成的构造函数必须是const工厂构造函数只能返回固定、已知约enum实例之一。
不能扩展其他类,因为Enum会自动扩展。
不能为索引,hashCode,等值运算持……进行覆盖。
denum中不能声明名为values的成员,因为它会与自动生成的静态values getter冲突。
所有enum的实例必须在声明的开始处声明,并且必须至少声明一个实例,在增强enum中的实例方法可以使用this引用当前的enum值。
以下是一个声明具有多个实例、实例变量、getter和实现接口的增强enum约的示例:
dart
void main() {
print(Person.woman);
print(Person.woman.tail);
print(Person.woman.index);
print(Person.values);
var color = Colors.red;
switch (color) {
case Colors.red:
print('red');
break;
default:
print('blue');
}
}
enum Colors {
red,
blue;
}
enum Person {
man(tail: 180, weight: 65),
woman(tail: 170, weight: 65);
final int tail;
final int weight;
const Person({required this.tail, required this.weight});
}
P102 dart3.0_01元组Record类型详解
//类型注释(类型,类型),例如(int,int)
4/Record类型注释是由括在括号中的类型的逗号分隔列表组成。您可以使用record类型注释来定义返回类型和参数类型。
void main() {
Record r1 = (88, 52);
print(r1.runtimeType);
(int, int) r2 = (88, 25);
print(r2.$1);
(int a, int b) r3 = (88, 25);
(int aa, int bb) r4 = (88, 25);
print(r3 == r4); //true
//对象相识 同名true 不同false
({int size, int weight}) apple = (size: 520, weight: 1314);
({int size1, int weight1}) apple1 = (size1: 520, weight1: 1314);
print(apple1 == apple); //false
}
P103 dart3.0_02模式的解构基本使用和元组R...
void main() {
var (v1, v2) = (88, 888);
print(v1);
Map m1 = {"name": 'koo'};
var {"name": name} = m1;
print(name);
var (age, user) = getInfo();
print(age.toString() + user);
}
(int, String) getInfo() {
return (88, 'koo');
}
P104 dart3.0_03模式匹配解构变量定义嘅值if_
//if case 是把case放在()小括号里面进行匹配,相当于单—一组的switch case
void main() {
var l1 = [1, 2];
switch (l1) {
// case [1, 2]:
// print('普通模式');
//默认有break 功能
case [int a, int b]:
print('$a $b');
}
var list = ['abc', 2];
switch (list) {
case ['abc' || 'b', 2]:
print('metch sussues');
}
if (list case [String str, int a]) {
print('$str $a');
}
var a = 1, b = 3;
(b, a) = (a, b);
print('$a,$b');
}
P105 dart3.0_04 switch表达式
//switch表达式 不能放在开头
void main() {
var x = 10;
var result = switch (x) {
10 => 'match 10',
20 || 30 => 'match 20 30',
_ => 'default'
};
print(result);
}
P106 dart3.0_05模式解构实例对象switch语句…..
/解构类实例
/对象模式匹配,允许给类的对象,里面getter进行解构
/所有实例变量生成一个隐式的 getter方法。
非 final 实例变量和没有初始化器的延迟 final 实例变量也会生成一个隐式的 setter 方法。/要解构类的实例,使用var或者final在类名称后面加0括号,里面用getter:加上用来解构创建的变量
ا/getter同名的时候可以省略
void main() {
var Person(name: n1) = Person('koo');
n1 = 'john'; //final 声明的无法改变
// var Person(:name) = Person('koo');//key===value 简写
var p1 = Person('koo');
switch (p1) {
case Person(name: var n) || Student(name: var n) when n == 'koo':
print('====');
}
}
class SW {}
class Person extends SW {
var name;
Person(this.name);
get GetName {
return 'person name';
}
}
class Student extends SW {
var name;
Student(this.name);
get GetName {
return 'Student name';
}
}
P107 dart3.0_06sealed封闭的类switch模式匹配
sealed为了创建一个已知的可枚举子类型集合,您需要使用sealed修饰符。这使您能够创建一个对所有这些子类型的switch语句,而该语句在编译时被确定为宝sealed 修饰符阻止一个类在其自身库之外被扩展或实现。密封类是隐式抽象的。
它们不能自己被实例化。它们可以有工厂构造函数。
它们可以为它们的子类定义构造函数。然而,密封类的子类不是隐式抽象的。
编译器知道所有可能的直接子类型,因为它们只能在同一个库中存在。这允许编译器在switch语句的case中没有穷举所有可能的子类型时发出警告:如果你不想进行详尽的切换,或者希望在添加子类型时不会破坏 API,可以使用final 修饰符。要深入了解 sealed 和 final 的比较,请阅读 sealed 与 final 的
文件外,不能继承sealed类型的class
/sealed的子类,可以被继承
sealed 和 final 的区别
如果你有一个你不希望用户能够直接创建子类型的类,那么在什么情况下应该使用 sealed 而不是 final?有一些简单的规则:
sealed 和 final 的区别
如果你有一个你不希望用户能够直接创建子类型的类,那么在什么情况下应该使用 sealed 而不是 final?有一些简单的规则:
如果你希望用户能够直接构造类的实例,那么不能使用 sealed,因为sealed 类型是隐式抽象的。
如果你的库中的类没有子类型,那么使用 sealed 就没有意义,因为你无法获得详尽性检查的好处。
否则,如果该类有一些你定义的子类型,那么sealed可能是你想要的。如果用户看到该类有一些子类型,能够方便地将它们作为switch语句的不同情况处使用sealed意味着如果你以后在库中添加了另一个子类型,那么这将是一个破坏性的API更改。当出现新的子类型时,所有那些现有的switch语句都变得
final 类只final类 继承 //final class也不能在文件外被继承
void main() {}
sealed class SW {}
class Person extends SW {
var name;
Person(this.name);
get GetName {
return 'person name';
}
}
class Student extends SW {
var name;
Student(this.name);
get GetName {
return 'Student name';
}
}
P108 dart3.0_07forin模式解构Map模式解构验.
void main() {
Map m1 = {'name': 'koo', 'age': 88};
for (var item in m1.entries) {
print('${item.key} + ${item.value}');
}
var MapEntry(:key, :value) = MapEntry('koo', 88);
// var json = {
// "name": 'koo',
// "job": ['coder', 'admin']
// };
// var {"job": [job1, job2]} = json;
// print(job1);
}
P109 dart3.0_08模式优先级 逻辑或逻辑与等...
P110 dart3.0_09模式中的强制类型转换
as
void main() {
num n1 = 88;
n1 = 88.8;
var n2 = (n1 as int);
// n2 = 88.8;
}
P111 dart3.0_10模式中的空检查null-heck
//空检查(Null-check)
//格式:子模式?,例如:switch 中的{case var s?..}
//空检查模式首先匹配值是否不为null,然后使用相同的值匹配内部模式。它们允许您绑定一个变量,该变量的类型是可匹配的可空值的非空基础类型。
//上面内容有点拗口,意思就是,空检查可以把传进来的可空的类型的String?用一个String的非空类型去接受,如果String?里面存的值是null,那么匹配失败,向1
/空检查的作用是,遇到null 值视为匹配失败而不抛出异常,遇到非空的就接受并且绑定非空值
void main() {
// String? str = 'koo';
String? str = null;
nullCheck(str);
}
nullCheck(str) {
switch (str) {
case var s?:
print('$s not null');
case null:
print('null');
}
}
P112 dart3.0_11模式中的空断言Null-assert
void main() {
// String? str = 'koo';
String? str = null;
nullAssert(str);
}
nullAssert(str) {
try {
switch (str) {
case var s!:
print('$s not null');
}
} catch (e) {
print(e);
}
}
P113 dart3.0_12常量模式
//常量模式在值等于常量时匹配:
//123,null、'string'、ml
.pi,SomeClass.constant,const Thing(1,2),const(1+2)
//例如我们在空检查里面无法匹配到null,但是常量模式可以匹配null
//可以作为常量模式的格式有:
//数字字面量123、45.56
//布尔字面量true
/字符串字面量'string'
//命名常量(宏定义)someConstant,math.pi,double.infinity
//常量构造函数const Point(0,0)
//常量集合字面量例如List const[]、集合const(1,2)
//更复杂的常量表达式必须用括号括起来,并加上 const 前缀const(1 + 2)
void main() {
int? a = 3;
switch (a) {
case null:
print('null');
case const (1 + 2):
print('3');
}
}
P114 dart3.0_13变量模式
var
P115 dart3.0_14标识符模式括号优先级列表Li...
标识符
例如
//name常量名称,在外面定义的const常量11-通配符,匹配全部,并且不存储结果
//标识符模式在出现它们的上下文中可能像常量模式或变量模式一样行为
//case[a,b]://外层先匹配List列表模式,然后递归匹配里面的常量模式,进行解构
//print('先匹配整体List模式,在匹配常量子模式 $a,$b');ceabe列率塔式的数面对应
void main() {
List list = [1, 2, 3];
const a = 1;
const b = 2;
switch (list) {
case [a, b]:
print('const');
case [var a, var b]:
print('var');
case _:
print('-');
// _ 获取全部了
default:
print('default');
}
}
P116 dart3.0_15模式Rest元素占位三个点创建
11列表模式要求模式中的元素数量与整个列表相匹配。你可以使用 rest 元素作为占位符来处理列表中的任意数量的元素。
//Rest 元素
11列表模式可以包含一个rest 元素…..),允许匹配任意长度的列表。
void main() {
List list = [1, 2, 3, 4, 5, 6];
var [a, b, ...rest, x, y] = list;
print('$a $b $x $y');
print(rest);
}
P117 dart3.0_16类修饰符base
版本说明:除了abstract之外,类修物行需要至少3.0的语言版本。
类修饰符控制类成混合录的使用方式,既可以从其自己的库内都使用,也可以从定义它的库外都使用。
修他关键字出现在类成混合类声明之前,例如,编写abstract class定义了一个抽拿类,可以在类声明之前使用的完整传的行生包:
abstract base final interface sealed mixin只有base特饰持可以出现在消合负声明之前。这些修饰并不适用于属他声明,tenum,typede乱estension,在决定是否使用类排饰用时,请考虑类的预期用途以及负需要位用的行为。
注意:如果作理护一个库,请阅读AP维护en类修你特支素,丁解如何为向的车导机这世更改的s导无修饰养
为了允许从任何库构造成派生由,可以使用没有修体行的角成混合资声明,默认情况下,你可从:
构造类的新实例。
扩展角以创建新的于典型。实现角成混合类的横口。洗入混合类成混合类。
abstract为了定又一个不需要完整具体实现其整个操口的类,请使用abstract修体得。
抽象类不能从任何库构造,无论是自己的车还是外部库,๒常类通常其来抽方法。
dart
无修饰符是之前定义的默认的类
abstract 类修饰符 是定义的抽象类
base base修饰符。基类禁止在其自己的库之外implements。这保证了当创建类的子类型的实例时,基类构造函数被调用
所有实现的私有成员在子类型中存在.
基类中的新实现成员不会破坏子类型,因为所有子类型都继承了新成员。这是真的,除非子类型已经声明了具有相同名称但签名不兼容的成员必须将任何实现或扩展基类的类标记为base,final或sealed,这样可以防止外部库破坏基类的保证。基
子类必须是base、final或sealed
void main() {}
base class Person {}
base class Student extends Person {}
final class Student1 extends Person {}
sealed class Student2 extends Person {}
base class Student3 implements Person {}
P118 dart3.0_17类修饰符final类
final修饰符。这可以防止来自当前库之外的类进行子类型化。禁止继承和实现都可以完全阻止子类型化。这保证了:您可以安全地向 API 中添加增量更改。
您可以调用实例方法,确保它们尚未在第三方子类中被覆盖。
final 类可以在同一库中被扩展或实现。final 修饰符包含了 base 的效果,因此任何子类也必须标记为 base、final 或 sealed
P119 dart3.0_18类修饰符interface接口
接口(interface)
为了定又一个接口,使用 interface 修饰符,在接口的定义库之外的库中可以实现该接口,但不能扩展它,这保证了:
1.可以实例化
2.不能被extends继承
3.可以被implents实现多个接口
为了定义一个接口,使用 interface 修饰符。在接口的定义库之外的库中可以实现该接口,但不能扩展它。这保证了:
1.可以实例化
2.在当前库之外不能被extends继承,本库中可以
3.可以被implements实现多个接口
void main() {
var p1 = Person();
p1.run();
var s1 = Student();
s1.run();
var w1 = Worker();
w1.run();
}
// abstract interface class Person {
// run();
// }
interface class Person {
run() {
print('run');
}
}
class Student extends Person {}
class Worker implements Person {
@override
run() {
print('work');
}
}
P120 dart3.0_19mixin混入和implements的区别
mixin mixin 混人
mixin 类声明需要至少 3.0 的诗言版本。
mixin比implements的好处是,在多层次烟承的时候,不需要强制重写所有方法,音通方法可以直确继承过来使用普通的 extends单线出承和implements多糖承,无法满足一些要求,所以出现了满入mixin,混入的非抽象方法可以直接使用,不需要重等,可以降低晒合度
1.可以完成多层次爆承:可以同时 extends一个父类,再用with混入多个 mixin 父类2.普通的多维承是用implements 实现,这个要求把所有父类和接口的所有属性和方法都重写实现mixin也是多维承,但是他原implements的区制来,使用with关键字黑人的mixin可以像estends那排使用,就是只有抽象方法才强制重写实现,音通方法可以不实现,直接继承过来使用。
3.mixin class可以直接创建对象,mixin不能创建对象
4.mixin class不能创建抽象方法,miin可以制建抽象方法
5.on关键字,限制mixin可以被一个类的子失黑入例声明misin A on Person,代AAR@被Base的于免黑人,例tclass Student extends Persan with A
6.抽象 misin类.abstract misin class因为是class,所以可以被extends思承,因为是abatract,所以可以有象方泳 l
7.国人继承多个mixin父类,有相同名字的方法,后想手的会理盖光根来的
//只用mixin修饰符,不加class不能创建对象
/5.on关键字,限制 mixin可以被哪个类继承混入 例如 声明 mixin A on Base,代表 A只能被 Base继承
void main() {
var p1 = Person();
p1.run();
var s1 = Student();
s1.run();
var w1 = Worker();
w1.run();
}
class Person {
run() {
print('run');
}
}
mixin M1 on Person {
eat();
}
mixin class M2 {
walk() {}
}
class Student extends Person with M1, M2 {
@override
eat() {
// TODO: implement eat
throw UnimplementedError();
}
}
class Worker implements Person {
@override
run() {
print('work');
}
}
P121 dart3.0_20切换dart和flutter版本降低版本
P122 dart3.0_21dart3修改的2的语法命名可选…..
git tag
git checkout branch
flutter --version 就下载其他东西
//dart3.0之前,命名可选参数的默认值,可以用冒号:,也可以用等号=,但是3.0之后,只能用=
fun({String name:'koo'}){}
fun({String name='koo'}){}
P123 dart3.0_22空安全切换版本2.12前后
Never Null
str?.length 为空不执行/返回null
isEven isOdd
a?..fn();
?为空不执行/返回null
str!.length !强转 如果null 就error as也是
P124 dart3.0_23空安全短路跳过和级联下标索
Type promotion类型模升,通过判断,去徐空典型,相当于可造类型,发现是奉空的以后党成卷通类型,也可以建解可选类型强制解气is判断类型,可以进行类型换升
事空安全下,因为没有可给类型,只有基本类型,所以不存在类型提升的去空化,就是不存在通线判断i作(a(-null)把String?变成String空安全下存在可造类型,去空化之后可以方使调用基本类型的方法
1.= null
2.1n mull
3.is 某个类型
4.is!某个类型
5.强制解包后类型提升
可选类型 == null 空安全下的类型提升
P125 dart3.0_24空安全下类型提升判断是否为….
P126 dart3.0_25空安全下类型提升判断is子类..
P127 dart3.0_26空安全中用late代替可选类型
在空安全情况下,类中的成员变量,如果在定义类的时候没有初炒值,那么默认值是nul定义这个类型就委用可选类型,例如tring?str1解决这个默认值不是nul的问题用late.这样可以在后续的操作中,不使用str?.方法,而直接使用str.i
String str ="";//最佳解决方案
P128 dart3.2_01_final私有成员类型提升
P129 dart3.3_01 extension type扩展类型1
发布日期:2024年2月15日1Dart33
Dart 3.3 为语言添加了一些增强动能
扩展类型是 Dart 中的一个新功能,允许零成本地包装现有典型,它们类似于包装器类和扩展方注,但具有不用的实现差用和不用的权断。
在扩展类型的主体中声明成员,以与类成员相同的方式定义其掉口,r展类型成员可以是方法,petter,setter成运算将(不光许事外都实例变量和抽象成员):
(inti)里面软的是成层的内置成质变量inti,也可以放自定义的类
extension type intid(int i
/状里的inti在类型中是内置的成員安量,有内置的getter.可以 满用 对象i/例物varil=intia(100)
operator <(intid other)=>i< other.
//intid(this.i:扩报错,这个构造函数差系统已经定义的想式构造函数,不能自已重定又
/Can't use'Intid'because it is deciared more than once不能使用intid,四为它被声明丁多次Intid.n(this.i:从/命名构造画数,类名·方法名
Intid.m(intj,String foo)i+foo length://命名构造南歌
自动创建一个class
N
//Intid2.n(this.i)://系统默认生成了命名构造函数Intid2.n
Intid2(this.i)://默认的未命名构造函数在这里需要自己生成
P130 dart3.3_02 extension type扩展类型2
my Flutter 3.22.2
这个api 3.3+
void main() {
var id1=Intid(100);
id1.showId();
var id2=Intid(200);
id1<id2.i;
}
extension type Intid(int i){
showId()=>print('$i');
operator <(int other)=>i<other;
}
extension type Intid2.n(int i){
Intid2(this.i);
showId()=>print('$i');
operator <(int other)=>i<other;
}
P131 dart3.3_03 extension type扩展类型3
P132 dart3.3_04扩展类型使用implements继…
1.类型扩展
使用implements继承某个类,可以使用他下面所有方法和操作糊也可以继承这个类的父类
工厂构造函数重定向,使用等号
另一个在相同表示类型上有效的扩展类型,这使您可以在多个扩展类型之间重用操作
void main() {
var id1=Intid(100);
id1.showId();
}
extension type Intid(int i) implements int{
showId()=>print('$i');
}
P133 dart3.3_05扩展类型使用implements继…
void main() {
}
extension type Person(String name){
factory Person.x(String name)=Person;
factory Person.a(String name)=Student;
}
extension type Student(String name) implements Person{
Student.a(this.name);
}
重定向
P134 dart3.3_06扩展类型implements透明性….
透明性:当一个扩展类型用imple-bents 实现了他的表示类型(封装的成层类型),可以视为:透明,扩展类型可以当做未示类型来用不透明性:没有通过implements 实现他的表示类型。扩展类型不能当做表示类型来用
P135 dart3.3_07扩展类型implements透明性…
P136 dart3.3_08扩张方法使用as前缀和hide解…..
//普通的类也可以扩展
void main() {
var a=A();
a.show();
}
class A{}
extension B on A{
show()=>print('hello');
}
P137 dart3.3_09_static属性和方法getter和setter
void main() {
NewString.name = 'abc';
print(NewString.name);
NewString.show();
}
extension NewString on String {
static String name = 'koo';
static show() {
print('$name');
}
}
static 的 属性 自动创建了get set
P138 dart3.3_10_Extension methods方法扩展
11动态类型,不能调用扩展里面的方法,只有静态分析出来的类型,才能调用扩展里面的方法
void main() {
var a = '520'.parseInt();
print(a);
}
extension NewString on String {
int parseInt() {
try {
return int.parse(this);
} catch (e) {
print('out error');
return -1;
}
}
}
P139 dart3.4_01版本选择和切换
使用 json 宏
JsonCodable 宏尚不稳定,目前处于实验性标志后面。它仅适用于 Dart 3.5.0-152 或更高版本。这个版本可以从 Dart dev 通道或 Flutter master 通道获取。
P140 dart3.4_02Json宏的安装配置和试验运行
import 'package:json/json.dart';
@JsonCodable()
void main() {
var p1 = Person('koo', 29);
print(p1.toJson());
}
class Person {
int age;
String name;
Person(this.name, this.age);
}
P141 dart3.4_03toJson和fromJson
P142 dart3.4_04自己的转换工具
https://gitee.com/wx18903612715/flutter-model-making-tool
P143 dart3.5 unpack下载包命令
dart pub unpack dio
P144架构师选学-01子类override覆盖父类方….
//这个例子演示子类重写父类方法,传入参数的规定
当覆盖方法时,请使用正确的传入参数类型:(父类或者超类)
覆盖方法的参数必须是与父类中相应参数的类型相同或是其超类型。不要通过将类型替换为原始参数的子类型来“收紧”参数类注意:
如果您有使用子类型的有效理由,可以使用covariant关键字.
考虑Animal类的chase(Animal)方法:
class Animak
参数 传 父类 超类object 都行了
)O//正确 重写函数的参数是父类型方法的传入类型 或者 超类D//正确,参数是超类,父类方法中定义的传入参数的父类
/错误,重写的函数传入参数不能是子类,b
P145架构师选学-02子类中重写方法的返回类
void main() {}
class Animal {
Animal eat() {
return Animal();
}
getName(Animal a) {}
}
class Dog extends Animal {
// getName(Animal a) {}
// getName(Dog a) {} //error
// getName(Cat a) {} //error
getName(Object a) {}
// Animal eat() {
// return Animal();
// }
// Dog eat() {
// return Dog();
// }
// Cat eat() {
// return Cat();
// }
//error down
// Object eat() {
// return Object();
// }
Object eat1() {
return Object();
}
}
class Cat extends Animal {}
P146架构师选学-03.List的dynamic动态类型…
P147 架构师选学-04类型推断type inferece
P148第五章Flutter篇:---000flutter导读项目b...
P149 001_第一个flutter程序hello_flutter_runA...
P150 002最简单的MaterialApp主题和Scaffold.
P151 003Scaffold_appBaractions_Floating...
P152 004-a-StatefulWidget和State的语法结构
P153 004-b-setState刷新页面build方法热重启
P154 005_a_StatelessWidget无状态小部件不..
P157 006-02_StatefulWidget生命周期的initSt..
P155 005_b_build可以嵌套
P156 006_01_课前内容提要
P158 006-03-Container设置尺寸和背景颜色
P159 006-04-row-对齐方式mainAxisAlignme..
P160 006-05-column列的对其方式和Expand..
P161 006_06_container嵌套尺寸和decoration
P162 006_07_Align_container组合
P163 006_08_row和column_E轴mainAxisSiz...
P164 006-09_row_文字水平方向column的垂
P165 006_10_column的嵌套错误
P166 006_11_row的嵌套错误
P167 006_12_LocalKey重建时保存状态
P168 006-13-Globekey全局key父控件访问子
P169 007_00课前内容提要
P170 007-01-Scaffod的body规则
P171 007_02_Center和widthFactor和heightF...1
P172 007_03_image网络图片
P173 007_04a_image本地图片
P174 007_04b_image本地图片2容易出现的坑
P175 007_05_Padding设置其子组件内边距
P176 007_06_Container.margin外边距
P177 007_07_FlutterLogo图标和PlaceHolder...0
1.PlaceHolder()占位符
一个绘制一个方框的小部件,代表着其他小部件将来可能添加的位置。
在开发过程中,此小部件非常有用,可以指示界面尚未完全完成
默认情况下,占位符的大小适应其 container.
如果占位符位于一个无界空间中,或者某个维度是无限大它将根据给定的fallbackWidth 和fallbackHeight调整大小。
2.FlutterLogo图标,根据给定的尺寸自动调整大小,符合主题样式
P178 007_08_ListView children
P179 007_09_ListView_builder.itemBuilder使用
P180 007_10_ListView的分隔符separatorBuil...0
ListView.separated 自带分隔符属性
P181 007_11_ListView的builder.itemExtentBu..
Chid: Listview.Dullat itemExtentBuilder:
P182 007_12-13ListView生命周期和空列表转...
P183 007_14_ListTile.selected选中状态
P184 007_15_CheckBox复选框
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_rx/get_rx.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'flutter',
theme: ThemeData(primarySwatch: Colors.blue),
home: Home());
}
}
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool? flag = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter')),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
body: Demo());
}
Widget Demo() {
return Center(
child: Checkbox(
value: flag,
onChanged: (value) {
setState(() {
flag = value;
});
},
));
}
}
P185 007_16_IconButton图标按钮
P186 007_17_购物车例子_shopping cart例子.
P187 007-18-扩大点击区域ColoredBox透明色
P188 007_19点击改变actions
P189 007_20模型数据和Map的区别和优势
P190 007_20b_01模型制作工具使用教程1基...
P191 007_20b_02模型制作工具使用教程2网...
P192 007_20b_03模型制作工具使用教程3原...
P193 007_20b_04模型工具gitee仓库
https://gitee.com/wx18903612715/flutter-model-making-tool
P194 007_21_ListView中添加模型
P195 007_22添加和隐藏checkBox选中
P196 007_23_中间占位区域和右边IconButton
P197 007_24-27合集
P198 007_28-30合集
2 4 4+
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇