# dart **Repository Path**: lin3308/dart ## Basic Information - **Project Name**: dart - **Description**: 大地Dart教程 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2022-01-24 - **Last Updated**: 2023-04-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 变量 ## 弱类型 ### var 如果没有初始值,可以变成任何类型 ```dart var a; // var a = ""; // 一旦赋值,就确定类型,不能随意改动 a = 'ducafecat'; a = 123; a = true; a = {'key': 'val123'}; a = ['abc']; print(a); ``` ### Object 动态任意类型 编译阶段检查类型 ```dart Object a = 'doucafecat'; a = 123; a = [2222]; a.p(); ``` ### dynamic 动态任意类型 编译阶段不检查检查类型 ```dart dynamic a = 'doucafecat'; a = 123; a = [1111]; a.p(); ``` ### 比较 var 与 dynamic、Object 唯一区别 var 如果有初始值,类型被锁定 ```dart var a = 'ducafecat'; dynamic a = 'doucafecat'; Object a = 'doucafecat'; a = 123; ``` ## 强类型 ### 申明类型 声明后,类型被锁定 ```dart String a; a = 'ducafecat'; a = 123; ``` ### 常见类型 | 名称 | 说明 | | ------------ | ------------- | | num | 数字 | | int | 整型 | | double | 浮点 | | bool | 布尔 | | String | 字符串 | | StringBuffer | 字符串 buffer | | DateTime | 时间日期 | | Duration | 时间区间 | | List | 列表 | | Sets | 无重复队列 | | Maps | kv 容器 | | enum | 枚举 | ```dart String a = 'doucafecat'; int i = 123; double d = 0.12; bool b = true; DateTime dt = new DateTime.now(); List l = [ a, i, d, b, dt]; ``` ## 默认值 变量声明后默认都是 `null` ```dart var a; String a; print(a); assert(a == null); ``` > `assert` 检查点函数,如果不符合条件直接抛出错误并终止程序进程 ## 使用场景 ### var 简化定义变量 不用明确变量类型 ```dart var map = {}; map["image"] = image; map["title"] = title; map["desc"] = desc; ``` > 这里不用 `var` ,就要写成 `Map` ### 查询参数定义 api 查询通用接口封装的时候,我们一般用动态类型 如一个 api 请求 ```dart Future> get( String path, { Map queryParameters, ... }); ``` > `Map? queryParameters`, 查询参数值是动态 ### 返回的实例对象 如分类实例定义 ```dart class Category { int id; // 数字 id String name; // 字符串 分类名称 String slug; Category({this.id, this.name, this.slug}); ... } ``` > `int id;` `String name;` 明确类型 # 常量 ## 相同点 ### 类型声明可以省略 ```dart final String a = 'ducafecat'; final a = 'ducafecat'; const String a = 'ducafecat'; const a = 'ducafecat'; ``` ### 初始后不能再赋值 ```dart final a = 'ducafecat'; a = 'abc'; const a = 'ducafecat'; a = 'abc'; ``` ### 不能和 var 同时使用 ```dart final var a = 'ducafecat'; const var a = 'ducafecat'; ``` ## 不同点 ### 需要确定的值 ```dart final dt = DateTime.now(); const dt = const DateTime.now(); ``` ### 不可变性可传递 ```dart final List ls = [11, 22, 33]; ls[1] = 44; const List ls = [11, 22, 33]; ls[1] = 44; ``` ### 内存中重复创建 ```dart final a1 = [11 , 22]; final a2 = [11 , 22]; print(identical(a1, a2)); const a1 = [11 , 22]; const a2 = [11 , 22]; print(identical(a1, a2)); ``` > `identical` 通过比较两个引用的是否是同一个对象判断是否相等 ## 使用场景 ### final 成员变量初始 ```dart class PlaceholdWidget extends StatelessWidget { final String? assetImagePath; const PlaceholdWidget({ Key? key, this.assetImagePath, }) : super(key: key); @override Widget build(BuildContext context) { ... } } ``` ### const 全局参数 ```dart // 本地存储key static const storageFirstOpen = 'first_open'; static const storageLanguageCode = 'language_code'; static const storageThemeCode = 'theme_code'; static const storageToken = 'token'; static const storageProfile = 'profile'; ``` # 数值 ## 数值转换 ```dart // string -> int // string -> double int a = int.parse('123'); double b = double.parse('1.223'); // int -> string // double -> string String a = 123.toString(); String b = 1.223.toString(); print([a, b]); // double -> int double a = 1.8; int b = a.toInt(); print(b); ``` # 布尔 ## 声明 为了代表布尔值,Dart 有一个名字为 bool 的类型。 只有两个对象是布尔类型的:true 和 false 所创建的对象, 这两个对象也都是编译时常量。 [bool](https://api.dartlang.org/stable/2.17.1/dart-core/bool-class.html) ```dart bool a; print(a); ``` ## true 判断 只有 true 对象才被认为是 true。 所有其他的值都是 flase。 ```dart String name = 'ducafecat'; if(name) { print('this is name'); } ``` ## assert 断言 ```dart var a = true; assert(a); var name = ''; assert(name.isEmpty); assert(name.isNotEmpty); var num = 0 / 0; assert(num.isNaN); ``` > 注意: 断言只在检查模式下运行有效,如果在生产模式 运行,则断言不会执行。 ## 逻辑运算符 ### `&&` 逻辑与 ```dart bool a = true; bool b = true; assert(a && b); ``` ### `||` 逻辑或 ```dart bool a = true; bool b = false; assert(a || b); ``` ### `!` 逻辑非 ```dart bool a = true; bool b = !a; print(b); ``` ## 关系运算符 ### `==` 等于 ```dart if(a == b) {} ``` ### `!=` 不等于 ```dart if(a != b) {} ``` ### `>` 大于 ```dart if(a > b) {} ``` ### `>=` 大于或等于 ```dart if(a >= b) {} ``` ### `<` 小于 ```dart if(a < b) {} ``` ### `<=` 小于或等于 ```dart if(a <= b) {} ``` # 字符串 ## 单引号或者双引号 - 赋值 ```dart String a = 'ducafecat'; String b = "ducafecat"; ``` - 区别 转义分隔符 ```dart String a = 'ducafecat'; String b = "ducafecat"; ``` ## 字符串模板 ```dart String a = 'ducafecat'; String b = "ducafecat"; ``` ## 字符串连接 ```dart var a = 'hello' + ' ' + 'ducafecat'; var a = 'hello'' ''ducafecat'; var a = 'hello' ' ' 'ducafecat'; var a = 'hello' ' ' 'ducafecat'; var a = ''' hello word this is multi line '''; var a = """ hello word this is multi line """; print(a); ``` ## 搜索 ```dart var a = 'web site ducafecat.tech'; print(a.contains('ducafecat')); print(a.startsWith('web')); print(a.endsWith('tech')); print(a.indexOf('site')); true true true ``` ## 提取数据 ```dart var a = 'web site ducafecat.tech'; print(a.substring(0,5)); var b = a.split(' '); print(b.length); print(b[0]); web s 3 web ``` ## 大小写转换 ```dart var now = new DateTime.now(); print(now); 2022-05-28 20:04:43.607 ``` ## 裁剪 判断空字符串 ```dart var now = new DateTime.now(); print(now); 2022-05-28 20:04:43.607 ``` ## 替换部分字符 ```dart print('hello word word!'.replaceAll('word', 'ducafecat')); hello ducafecat ducafecat! ``` # 日期时间 ## 声明 - 当前时间 ```dart var now = new DateTime.now(); print(now); 2022-05-28 20:04:43.607 ``` - 指定年月日 ```dart var d = new DateTime(2018, 10, 10, 9, 30); print(d); 2018-10-10 09:30:00.000 ``` ## 创建时间 UTC - [UTC 协调世界时](https://zh.wikipedia.org/wiki/%E5%8D%8F%E8%B0%83%E4%B8%96%E7%95%8C%E6%97%B6) - [原子时](https://zh.wikipedia.org/wiki/%E5%8E%9F%E5%AD%90%E6%97%B6) - [原子钟](https://zh.wikipedia.org/wiki/%E5%8E%9F%E5%AD%90%E9%90%98) - 时区表 ![](https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/20220528200356.png) - 创建 utc 时间 ```dart var d = new DateTime.utc(2018, 10, 10, 9, 30); print(d); 2018-10-10 09:30:00.000Z ``` ## 解析时间 IOS 8601 - [ISO 8601](https://zh.wikipedia.org/wiki/ISO_8601) - [时区](https://zh.wikipedia.org/wiki/%E6%97%B6%E5%8C%BA) - [时区列表](https://zh.wikipedia.org/wiki/%E6%97%B6%E5%8C%BA%E5%88%97%E8%A1%A8) - 如果时间在零时区 ```dart var d1 = DateTime.parse('2018-10-10 09:30:30Z'); print(d1); 2018-10-10 09:30:30.000Z ``` ```dart var d2 = DateTime.parse('2018-10-10 09:30:30+0800'); print(d2); 2018-10-10 01:30:30.000Z ``` ## 时间增减量 ```dart var d1 = DateTime.now(); print(d1); print(d1.add(new Duration(minutes: 5))); print(d1.add(new Duration(minutes: -5))); 2022-05-28 22:09:12.805 2022-05-28 22:14:12.805 2022-05-28 22:04:12.805 ``` ## 比较时间 ```dart var d1 = new DateTime(2018, 10, 1); var d2 = new DateTime(2018, 10, 10); print(d1.isAfter(d2)); print(d1.isBefore(d2)); false true ``` ```dart var d1 = DateTime.now(); var d2 = d1.add(new Duration(milliseconds: 30)); print(d1.isAtSameMomentAs(d2)); false ``` ## 时间差 ```dart var d1 = new DateTime(2018, 10, 1); var d2 = new DateTime(2018, 10, 10); var difference = d1.difference(d2); print([difference.inDays, difference.inHours]); [-9, -216] ``` ## 时间戳 - [公元](https://zh.wikipedia.org/wiki/%E5%85%AC%E5%85%83) ```dart var now = new DateTime.now(); print(now.millisecondsSinceEpoch); print(now.microsecondsSinceEpoch); 1653747090687 1653747090687000 ``` # Map ## 初始 key value 形式的集合,也叫键值对。 ```dart var a = {'name': 'ducafecat', 'web': 'www.ducafecat.tech'}; print(a); {name: ducafecat, web: www.ducafecat.tech} ``` ## 声明 ### 松散 ```dart var a = Map(); a['name'] = 'ducafecat'; a['web'] = 'www.ducafecat.tech'; a[0] = 'abc'; a[0] = '1231231'; print(a); {name: ducafecat, web: www.ducafecat.tech, 0: 1231231} ``` key 相同,覆盖数据 ### 强类型 ```dart var a = Map(); a[0] = 'java'; a[1] = 'python'; print(a); {0: java, 1: python} ``` ## 基本属性 | 名称 | 说明 | | ---------- | ------------ | | isEmpty | 是否为空 | | isNotEmpty | 是否不为空 | | keys | key 集合 | | values | values 集合 | | length | 个数 | | entries | 加工数据入口 | ```dart var a = {'name': 'ducafecat', 'web': 'www.ducafecat.tech'}; print(a.isEmpty); print(a.isNotEmpty); print(a.keys); print(a.values); print(a.length); print(a.entries); false true (name, web) (ducafecat, www.ducafecat.tech) 2 (MapEntry(name: ducafecat), MapEntry(web: www.ducafecat.tech)) ``` ## 常用方法 | 名称 | 说明 | | ------------- | ------------- | | addAll | 添加 | | addEntries | 从入口添加 | | containsKey | 按 key 查询 | | containsValue | 按 value 查询 | | clear | 清空 | | remove | 删除某个 | | removeWhere | 按条件删除 | | update | 更新某个 | | updateAll | 按条件更新 | ### addAll 新增 kv 数据 ```dart b.addAll({'first': 'java', 'second': 'python'}); ``` ### addEntries 接入另一个 map 集合 ```dart b.addEntries(a.entries); ``` ### containsKey 检查 key 是否存在 ```dart print(a.containsKey('name')); ``` ### containsValue 检查 value 是否存在 ```dart print(a.containsValue('www.ducafecat.tech')); ``` ### clear 清空数据 ```dart b.clear(); ``` ### remove 删除数据 ```dart a.remove('name'); ``` ### removeWhere 按条件删除 ```dart a.removeWhere((key,val) => key == 'name'); ``` ### update 更新数据 ```dart a.update('name', (val) => 'abc'); ``` ### updateAll 更新批量 ```dart a.updateAll((key, val) => "---$val---"); ``` ## 操作符 | 名称 | 说明 | | ---- | ---- | | [] | 取值 | | []= | 赋值 | ```dart print(a['name']); a['name'] = 'abc'; ``` # Set ## 声明 `Set` 是一个元素唯一的有序队列 ### 松散 ```dart var a = Set(); a.add('java'); a.add('php'); a.add('python'); a.add('java'); a.add('sql'); a.add('swift'); a.add('dart'); print(a); {java, php, python, sql, swift, dart} ``` ### 强类型 ```dart b.addAll(['dart', 'c#', 'j#', 'e#']); print(b); {dart, c#, j#, e#} ``` ### 去重 & 转列表 ```dart var ls = ['dart', 'java', 'c#', 'j#', 'e#', 'java']; var tags = Set(); tags.addAll(ls); print(tags); print(tags.toList()); {dart, java, c#, j#, e#} [dart, java, c#, j#, e#] ``` ## 基本属性 | 名称 | 说明 | | ---------- | ---------- | | isEmpty | 是否为空 | | isNotEmpty | 是否不为空 | | first | 第一个 | | last | 最后一个 | | length | 个数 | ## 常用方法 | 名称 | 说明 | | ------------ | -------------------- | | addAll | 添加 | | contains | 查询单个 | | containsAll | 查询多个 | | difference | 集合不同 | | intersection | 交集 | | union | 联合 | | lookup | 按对象查询到返回对象 | | remove | 删除单个 | | removeAll | 删除多个 | | clear | 清空 | | firstWhere | 按条件正向查询 | | lastWhere | 按条件反向查询 | | removeWhere | 按条件删除 | | retainAll | 只保留几个 | | retainWhere | 按条件只保留几个 | ```dart // b.addAll(['dart', 'c#', 'j#', 'e#']); // print(b.contains('dart')); // print(b.containsAll(['dart', 'swift'])); // print('b => $b'); // print(a.difference(b)); // print(a.intersection(b)); // print(b.lookup('dart')); // print(b.union(a)); // b.remove('dart'); // b.removeAll(['dart','c#']); // b.clear(); // print(b.firstWhere((it) => it == 'c#')); // print(b.lastWhere((it) => it == 'c#')); // b.removeWhere((it) => it == 'c#'); // b.retainAll(['e#']); // b.retainWhere((it) => it == 'e#'); // b.retainWhere((it) { // bool ret = it == 'e#'; // return ret; // }); ``` ### 交集 ```dart var fd = {"js", "node", "dart", "css", "html", "macos", "docker", "git"}; var ed = {"linux", "docker", "git", "go", "python", "sql", "node", "js", "aws"}; print(fd.intersection(ed)); {js, node, docker, git} ``` ### 联合 ```dart var fd = {"js", "node", "dart", "css", "html", "macos", "docker", "git"}; var ed = {"linux", "docker", "git", "go", "python", "sql", "node", "js", "aws"}; print(fd.union(ed)); {js, node, dart, css, html, macos, docker, git, linux, go, python, sql, aws} ``` # 枚举 ## 定义 适合用在常量定义,类型比较很方便。 ```dart // 定义颜色枚举值 enum ColorType { none, red, green, blue, } void main(List args) { // 1 接收输入值 red 字符串 var input = "red"; // 2 将输入值转换为 ColorType 枚举类型 var color = ColorType.none; if (input == "red") { color = ColorType.red; } else if (input == "green") { color = ColorType.green; } else if (input == "blue") { color = ColorType.blue; } // 3 switch 判断,打印输出 switch (color) { case ColorType.red: print(ColorType.red); break; case ColorType.green: print(ColorType.green); break; case ColorType.blue: print(ColorType.blue); break; default: print(ColorType.none); } } ``` ## 使用场景 定义发帖类型 视频 图片 空 ```dart enum PostType { video, image, none } ``` 业务中判断 ```dart PostType get type { if (detail.type == POST_TYPE_IMAGE) { return PostType.image; } else if (detail.type == POST_TYPE_VIDEO) { return PostType.video; } else { return PostType.none; } } ... if (type == PostType.video && !_hasDetail) { playlist.insert(0, VideoMedia(detail)); } ... if (type == PostType.video) { if (playlist.isEmpty) { playlist.add(VideoMedia(detail)); } else { playlist.first.post = detail; } } } finally { _isLoading = false; if (type == PostType.video && !_hasDetail) getPostList(); } ``` # 函数 ## 定义 ```dart int add(int x) { return x + 1; } 调用 add(1); ``` ## 可选参数 ```dart int add(int x, [int? y, int? z]) { if (y == null) { y = 1; } if (z == null) { z = 1; } return x + y + z; } 调用 add(1, 2); ``` ## 可选参数 默认值 ```dart int add(int x, [int y = 1, int z = 2]) { return x + y; } 调用 int(1, 2); ``` ## 命名参数 默认值 ```dart int add({int x = 1, int y = 1, int z = 1}) { return x + y + z; } 调用 int(x: 1, y: 2); ``` ## 函数内定义 ```dart void main(){ int add(int x){ return x + x; } print(add(1)); } ``` ## Funcation 返回函数对象 ```dart Function makeAdd(int x) { return (int y) => x + y; } 调用 var add = makeAdd(1); print(add(5)); ``` ## 匿名函数 下面代码定义了只有一个参数 item 且没有参数类型的匿名方法。 List 中的每个元素都会调用这个函数,打印元素位置和值的字符串: ```dart const list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); }); ``` 箭头函数 如果只有一个表达式 ```dart list.forEach((item) => print('${list.indexOf(item)}: $item')); ``` ## 作用域 下面是一个嵌套函数中变量在多个作用域中的示例: ```dart bool topLevel = true; void main() { var insideMain = true; void myFunction() { var insideFunction = true; void nestedFunction() { var insideNestedFunction = true; assert(topLevel); assert(insideMain); assert(insideFunction); assert(insideNestedFunction); } } } ``` > 注意 nestedFunction() 函数可以访问包括顶层变量在内的所有的变量。 # 流程控制 ## if else ```dart bool isPrint = true; if (isPrint) { print('hello'); } ``` ## for ```dart for (var i = 0; i < 5; i++) { print(i); } ``` ## while ```dart bool isDone = false; while(!isDone) { print('is not done'); isDone = true; } ``` ## do while ```dart bool isRunning = true; do { print('is running'); isRunning = false; } while (isRunning); ``` ## switch case ```dart String name = 'cat'; switch (name) { case 'cat': print('cat'); break; default: print('not find'); } ``` ## break ```dart num i = 1; while(true) { print('${i} - run'); i++; if(i == 5) { break; } } ``` ## continue ```dart for (var i = 0; i < 5; i++) { if (i < 3) { continue; } print(i); } ``` ## continue 指定位置 ```dart String command = "close"; switch (command) { case "open": print("open"); break; case "close": print("close"); continue doClear; case "close2": print("close2"); continue doClear; doClear: case "doClose": print("doClose"); break; default: print("other"); } ```