Dart 语法核心 7 讲:变量 + 常量 + 数据类型 + 空安全 + 运算符 + 流程控制 + 函数
基础语法
1.变量var和常量const和final
变量(存储并修改数据)
- 声明变量:var 变量名 = 表达式;
- 修改变量:变量名 = 新值;
- 类型推断:var关键字声明的变量支持类型推断,修改变量时会检查之前存储数据的类型
void main() {// 变量的声明// 前端 var 鸿蒙 let constvar name = "变量";print(name);name = "变量能改变";print(name);const BASE_URL = "https://toutiao.itheime.net"; // 常量地址print(BASE_URL);// BASE_URL = "abc"; 常量地址不能被赋值
}
常量(存储不变的数据)
相同点:const 和 final都不能被修改
const 和 final的区别:
final:运行时常量,值在运行时赋值,值最晚可以在运行时确定
const:编译期常量,值在编译时赋值,值最开始可以在编译时确定(性能高)
void main() {var count = 10;var count2 = 20;const Safe_Top_Height = 30; // 定义顶部安全区的高度final Safe_Bottom_Height = count + count2; // 定义底部安全区的高度// Safe_Top_Height = 40;// Safe_Bottom_Height = 50;//final和const相同点: 都不能被修改// const 编译期的常量// final 运行时的常量// 编译- 程序- 编译过程-编译过了才可以运行// 运行-编译完成之后运行的代码print(Safe_Bottom_Height);// const性能更好,没运行的时候就确定了值和类型
}
2.数据类型(可存储数据类型)
num,int,double数字类型
num(整数 + 小数)、int整数、double整数(可以有小数)
如果确定是整数 用int 比如索引,数量,年龄
如果是价格,身高,考试分数等数据 用 double
都用num不好,num占的空间更大,占了整数和小数的空间
double可以存带小数的(哪怕给的是整数也会加.0 比如 90 运行的话,会呈现90.0)
void main() {// num声明的变量: 可以存 整数, 小数// 1. num声明的变量, 可以存整数和小数num age = 10;num money = 999999;// 2. int声明的变量, 只能存整数//储存的值一般: 索引值,循环次数,年龄int index = 0;// 3. double可以是整数, 也可以是小数,(也可以理解为存的整数)// double带精度的数字// double可以存带小数的(哪怕给的是整数也会加.0 比如 90 运行的话,会呈现90.0)// 价格,身高,考试分数double price = 9.9;double height = 168.5;print({age, money, index, price, height});
}// 总结// double不能给int赋值, int也不可以double赋值// double可以给num赋值, num不能给double赋值// int可以给num赋值String 字符串
String 变量=值
前端和鸿蒙字符串 可用反引号`${username}`,但flutter不能用反引号
换行写法:1,使用\n换行符、2,String 变量=''' 内容 ''' 前后三个引号中间写换行的内容
void main() {String username = "张三";print(username);username = "flutter真好学";print(username);// 前端和鸿蒙字符串 `${username}`//Flutter中不能用反引号// 只要不是计算的,都可以把模板字符串省略成$变量print('当前的用户名:$username');print('当前的用户名的长度:${username.length * 10}');// 使用\n换行符String poemStr = '白日依山尽\n黄河入海流\n欲穷千里目\n更上一层楼';print(poemStr);// 还有一种换行模式String song = '''Hiding from rain and snow,Looking at crowed from our around go
''';print(song);
}
bool布尔
bool 变量=true/false
flutter中的类型不支持隐性转化,!!0 不可取
flutter中没有全等===强类型语言, == 就是等同于前端鸿蒙中的全等
void main() {// 前端鸿蒙 showSheet: boolean = falsebool showSheet = true;if (showSheet) {print("半模态显示");} else {print("半模态隐藏");}// flutter支持三元表达式bool isMarry = false;isMarry ? print("已婚") : print("未婚");// flutter中的类型不支持隐性转化// 前端 鸿蒙 !!0int count = 0;bool isOK = count == 0; // flutter中没有全等 强类型语言 == 就是等同于前端鸿蒙中的全等
}
List 列表(类比 数组)
- flutter的列表常用的方法
- 定义列表 List 变量名 = [元素1, 元素2, ..., 元素n];
- add 在尾部添加数据、addAll 在尾部添加一个数组
- remove 删除满足内容的第一个、removeAt 根据索引删除、removeLast 删除最后一个
- removeRange删除索引范围内数据、forEach 循环、every 是否都满足条件、
- where 类似于前端鸿蒙的filter、last 最后一个元素、first 第一个元素、isEmpty 是否为空
数组前端鸿蒙
forEach循环-map返回新数组-find寻找-findIndex(寻找索引)-every(所有都满足)-some(有一个满足)
reduce(累计运行) filter(筛选) indexOf(寻找索引) pop(在尾部删除) push(在尾部追加) shift(在头部删除) unshift(在头部追加) slice(截取) splice(删除替换) join(链接) includes(包含) reverse(反转) flat(数组拍平方法)
void main() {// 前端 鸿蒙数组类型 1.Array<类型> 2. number[]// Flutter使用List关键字声明数组列表 -列表类型// var const final int num double String bool ListList indexList = [1, 2, 3];print(indexList);print(indexList[1]);// 数组前端鸿蒙 forEach-map-find寻找-findIndex(寻找索引)-every(所有都满足)-some(有一个满足)// reduce(累计运行) filter(筛选) indexOf(寻找索引) pop(在尾部删除) push(在尾部追加) shift(在头部删除) unshift(在头部追加) slice(截取) splice(删除替换) join(链接) includes(包含) reverse(反转) flat(数组拍平方法)// Flutter中常用方法// 追加操作indexList.add(4); // 追加操作print(indexList);//指定位置添加:列表.insert(索引, 内容');indexList.insert(0, 999);print(indexList);// 删除操作 删除具体数据indexList.remove(999);print(indexList);// 删除具体位置 索引indexList.removeAt(0);print(indexList);// 添加数组indexList.addAll([5, 6, 7]);print(indexList);// 删除最后一个indexList.removeLast();print(indexList);// 删除第一个// indexList.removeRange(0, indexList.length);// print(indexList);print(indexList.isEmpty); // 判断是否为空// 可以拿第一个最后一个if (indexList.length > 0) {print(indexList.first);print(indexList.last);}// 循环indexList.forEach((element) {print(element);});// 箭头函数只有一行逻辑的时候才可以写箭头函数 不能省略参数的括号indexList.forEach((element) => print(element));// every 筛选是否都满足条件print(indexList.every((element) => element > 0));// where方法类似filter方法print(indexList.where((element) => element > 4));// 直接使用for循环Listfor (int i = 0; i < indexList.length; i++) {print('当前循环的第$i个, ${indexList[i]}');}// for in循环for (var element in indexList) {print('当前的循环项$element');}
}
Map字典(类比 对象)
使用字典:查改增删
前端鸿蒙的对象类型 interface class 属性和类型是确定类型
Map Record 属于动态属性类型
前端鸿蒙中只有两个类型能用 [] 取值, object 和Record
void main() {// 前端鸿蒙的对象类型 interface class 属性和类型是确定类型// Map Record 属于动态属性类型// map: Map<string, number> = new Map() get set -ComponentContent(uiContext, wrapBuilder, options)// key a b c d 要用Record和Map// username password interface class// 前端鸿蒙中只有两个类型能用[]取值, object 和Record// flutter MapMap goodsMap = {"goods_name": "连衣裙"}; // 类似前端 let obj = {}// 读取和设置属性goodsMap["goods_id"] = 10001; // 设置商品订单编号goodsMap["goods_price"] = 108.34; // 设置商品订单编号goodsMap["goods_count"] = 20; // 设置商品订单编号print(goodsMap);goodsMap.remove("goods_count");print(goodsMap);// 循环goodsMap.forEach((key, value) {print('当前的key:$key,当前的value:$value');});
}
void main() {
// 1. 存储商品分类的编号 和 名称Map goods = {// 属性名key 要用""引起来,不然会被当作变量"fruit": "苹果","price": 20,"name": "手机",// 'count': 1,// 'isOnSale': true,// true: false,// 10: '123',// [1, 2, 3]: 10};// 2. 对字典数据进行查改增删
// 2.1 查询:字典[key]print(goods["price"]);// 2.2 修改:字典[key] = 新值goods["name"] = "电脑";// 2.3 新增:字典[新key] = 新值
// 注意:key必须是当前字典中不存在的key,如果key已存在就是修改goods["color"] = "粉色";// 2.4 删除:remove(key)
// 注意:如果key不存在,不会报错,也不会执行删除操作goods.remove("fruit");print(goods);// 3. 遍历字典// 方式1: for(var key in 字典.keys)for (var key in goods.keys) {print("key:$key,value:${goods[key]}");}// 方式2:for(var value in 字典.values)for (var value in goods.values) {print('value: $value');}// 方式3goods.forEach((key, value) {print('key: $key,value: $value');});
}

Dart空安全机制
Dart的空安全机制,默认所有的变量都是非空的,如果某个变量得到了一个null,代码在编译期就会报错
- 无法正常执行的代码:在代码编译期就会报错
- 解决办法:使用 ? 显示的指定变量可以为空
- 使用可以为空的变量
如果在编译期间发现变量有可能为空 直接编译不过
String? username;
username有可能为null也有可能为空字符串, 可以理解为 flutter String 和 null的联合类型
flutter 没有联合类型
void main() {// 如果在编译期间发现变量有可能为空 直接编译不过String? username; // username有可能为null也有可能为空字符串// 可以理解为 flutter String 和 null的联合类型// flutter 没有联合类型// 前端鸿蒙 avplayer: media.Avplayer | null = nullprint(username?.length);// ? 运行时检查和 !非空断言
}
void main() {
// 0. 正常代码String intro = 'hello world';print(intro.toUpperCase());// 1. 无法正常执行的代码:在代码编译期就会报错// String hobby;// print(hobby.toUpperCase());// 2. 解决办法:使用 ? 显示的指定变量可以为空String? hobby;print(hobby?.toUpperCase()); // null// 3. 使用可以为空的变量
// 如果demo没有值则返回null, 有值则返回正常的结果String? demo;// demo = 'hello world';print(demo ?? '没有值输出');
}
3.运算符(和前端鸿蒙的用法一样)
算数,赋值,比较,逻辑
void main() {// 加减乘除double salary = 10000; // 工资double start = 5000;double tax = (salary - start) * 0.05; // 税率double social = salary * 0.12; // 社保double fund = salary * 0.12; // 公积金double medicel = salary * 0.05; // 医保double other = salary * 0.02; // 养老 失业 生育 工伤double meals = 12 * 22; // 餐补double car = 10 * 22; // 车补double house = 500; // 房补print('应发工资:$salary,实际发放工资:${salary - tax - social - fund - medicel - other + meals + car + house}');int a = 10;int b = 3;print(a ~/ b); // 输出:3(因为 10 ÷ 3 = 3.33,取整为 3)
}
void main() {// 等于 =int n1 = 10;// 加等于 +=// n1 = n1 + 5;n1 += 5;print(n1); // 15// 减等于 -=n1 -= 5;print(n1); // 10// 乘等于 *=n1 *= 5;print(n1); // 50// 除等于 /=// 注意:double类型的数据才能做除等于的操作// A value of type 'double' can't be assigned to a variable of type 'int'.// n1 /= 5;double n2 = 50;n2 /= 5;print(n2); // 10.0// 取余等于 %=int n3 = 10;n3 %= 3;print(n3); // 1// 自增:在原有数值上加1 ++int a = 10;a++;print(a); // 11// 自减:在原有数值上减1 --int b = 20;b--;print(b); // 19
}
void main() {int n1 = 10;int n2 = 20;// 大于 >print(n1 > n2); // false// 小于 <print(n1 < n2); // true// 大于等于 >=print(n1 >= n2); // false// 小于等于 <=print(n1 <= n2); // true// 等于 ==print(n1 == n2); // falseprint('itcast' == 'itheima'); // false// 不等于 !=print(n1 != n2); // trueprint('itcast' != 'itheima'); // true
}
void main() {// 年龄int age = 33;// 工作年限int years = 10;// 1. 逻辑与:一假则假// 年龄大于28岁,并且工作年限大于4年bool ret1 = age > 35 && years > 4;print(ret1); // false// 2. 逻辑或:一真则真// 年龄大于23岁,或者工作年限大于2年bool ret2 = age > 35 || years > 2;print(ret2); // true// 3. 逻辑非:真变假,假变真print(!true); // falseprint(!false); // true// 工作年限不小于9年bool ret3 = years >= 9;// bool ret3 = !(years < 9);print(ret3); // true
}
4.流程控制(同TS)
判断:if+三元+switch
void main() {// 1. if单分支语句// 准备高考成绩,如果分数大于等于700分,则输出 '恭喜考入黑马程序员'int score1 = 699;if (score1 >= 700) {print('恭喜考入黑马程序员');}// 2. if双分支语句// 准备高考成绩,如果分数大于等于700分,则输出 '恭喜考入黑马程序员',反之,则输出 '继续努力'int score2 = 699;if (score2 >= 700) {print('恭喜考入黑马程序员');} else {print('继续努力');}// 3. if多分支语句// 根据学生分数划分学生成绩等级:// 优秀:分数大于等于90分// 良好:分数小于90分,且大于等于80分// 中等:分数小于80分,且大于等于60分// 不及格:分数小于60分int score3 = 58;if (score3 >= 90) {print('优秀');} else if (score3 >= 80) {print('良好');} else if (score3 >= 60) {print('中等');} else {print('不及格');}
}
void main() {// 需求:准备高考成绩,如果分数大于等于700分,则输出 '恭喜考入黑马程序员',反之,则输出 '继续努力'// 思考:以下代码可以简化吗?int score1 = 699;if (score1 >= 700) {print('恭喜考入黑马程序员');} else {print('继续努力');}// 1. 使用三元运算符简化if双语句:条件表达式 ? 表达式1 : 表达式2print(score1 >= 700 ? '恭喜考入黑马程序员' : '继续努力');// 2. 思考:以下代码适合使用三元运算符改写吗?int score2 = 88;if (score2 >= 90) {print('优秀');} else if (score2 >= 80) {print('良好');} else if (score2 >= 60) {print('中等');} else {print('不及格');}
}
main() {// 根据订单状态,打印出订单状态描述信息// 订单状态:1为待付款、2为待发货、3为待收货、4为待评价int orderState = 3;switch (orderState) {case 1:print('待付款');// break;如果不写break,在flutter中,会打印所有case下的内容,但是不会报错// 但是建议写breakak,防止程序员写错case 2:print('待发货');break;case 3:print('待收货');break;case 4:print('待评价');break;default:print('其他');}
}
循环:for+while+do while
main() {// 1. for 循环print('-----1. for 循环-----');for (int i = 0; i < 10; i++) {print(i); // 0 1 2 3 4 5 6 7 8 9}// 2. while 循环print('-----2. while 循环-----');int j = 0;while (j < 10) {print(j); // 0 1 2 3 4 5 6 7 8 9j++;}// 3. do while 循环print('-----3. do while 循环-----');int k = 0;do {print(k); // 0 1 2 3 4 5 6 7 8 9k++;} while (k < 10);// 4. 循环中断// break:跳出循环// continue:跳过当前循环,继续下一次循环print('-----4. 循环中断-----');for (int i = 0; i < 10; i++) {if (i == 5) {break;}if (i == 3) {continue;}print(i); // 0 1 2 4}// 列表循环print('-----5. 列表循环 for in -----');List<String> list = ['a', 'b', 'c', 'd', 'e'];for (String item in list) {print(item); // a b c d e}// 6. 列表循环 for 循环print('-----6. 列表循环 for -----');for (int i = 0; i < list.length; i++) {print(list[i]); // a b c d e}
}
