本文章主要用来记录自己的学习记录,没有教学初衷,如果觉得对你也适用的,那纯属巧合,哈哈.
- Dart官网:www.dartcn.com/ ,清晰的介绍了如何安装Dart官网,本文不赘述
- Dart官网编辑工具,免安装的DartPad很方便:dartpad.cn/? ,我还是喜欢VSCode,步骤很简单,第一步安装VSCdoe,第二步安装Dart和CodeRunner插件,学习Dart已经够了
- 接下来就是Dart语言学习,任何语言的学习,我认为就是三步:第一知道它能做什么,第二熟悉它的语法,第三用它开始做项目,本文先介绍它能做什么以及基础语法
一、Dart能做什么?
简介:
- Dart是谷歌开发的计算机编程语言,它被用于web、服务器、移动应用和物联网等领域的开发。所以,不要狭隘的认为,学习Dart就是为了学习flutter,Dart是开发语言,flutter只是一套使用Dart实现的UI框架。
特点:
- Dart是一种简洁、清晰的面向对象的语言,它是基于JavaScript的但是结构要比JavaScript要多。
- Dart是一种面向对象的、类定义的、垃圾回收语言。它支持接口、mixin、类对象,具有化泛型、静态类型等。
- 从Dart2.0开始,Dart成为强类型语言,在此之前,Dart为弱类型语言。
- Dart 属于应用层编程语言。它有自己的 DartVM ,通常情况下运行在自己的VM上,但是在特定情况下他也可以编译成 Native Code 运行在硬件上。
- Dart是AOT(Ahead Of Time)编译的,可编译成快速,可预测的本地代码,同时又可以JIT(Just In Time)编译,开发周期快,为flutter热重载提供基础。
- Dart的声明式编程布局,易于阅读和可视化,不需要单独的声明式布局语言,例如:XML,JSX等
- Dart语言被明确的分成了三个方向: 移动开发、DartVM 命令行程序(Server 端)、浏览器(前端)
总而言之,Dart语言应用领域并不单一,目前学习它的初衷是在移动开发领域对flutter的热爱。但是未来它可以做更多的事情。但是反过来说,Dart仅是我们工作中解决问题的一种选择,在特定的场景中使用最适合的语言编程才是一位合格开发工程师的做法,我们学习任何语言或者技术,目的都只是帮助自己工作的更加轻松。
二、Dart基础语法
任何面向对象语言的学习,基本可划分三个阶段的学习:初级、中级、高级,套用到Dart身上如下:
- 初级阶段:数据类型(集合、枚举)、变量、运算符、语句、分支、循环
- 中级阶段:函数(方法)、闭包、修饰符、类、对象、封装、继承、多态、方法重写
- 高级阶段:接口、抽象类、混入、高阶函数、泛型、异步
1. Dart中的数据类型
数据类型其实就是个内存容器,有人把一个进程或者操作系统比作家里吃饭的餐桌,开发这个进程或系统的语言中的数据类型好比放在餐桌上的餐具,餐桌上要用到盘子、碗和汤盆等,如果用盘子装汤就会溢出,用汤盆装菜就会浪费空间,所以我们要做的就是根据合适的食材选择合适的餐具。同理,在开发过程中,我们要结合系统需求存放的数据选择合适的数据类型。(真的感觉自己有点啰嗦🤦🏻♀️)
//常见常用数据类型
num(数值类型)
String(字符串类型)
bool(布尔类型)
List(列表类型)
Set(集合类型)
Map (映射类型)
//不常用数据类型
Runes (符文类型)
Symbol (符号类型)
//特殊类型
dynamic(动态数据类型修饰符,任何类型)
- num类型
num在Dart中表示数值类型,Dart中只有两种数值类型:int(整型)、double(浮点型)。
//num类型既可以表示int类型,也可以表示double
num a = 10;
a = 20;
print(a);//20
//num类型变量可以被赋值整型或浮点型都可以
a = 10.5;
print(a);//10.5
//但如果被指定了int类型,就不能再接收doubule类型的赋值
int b = 10;
//b = 10.5;//报错:A value of type 'double' can't be assigned to a variable of type 'int'.
//double类型变量可以被赋值为int类型(其实就是汤盆可以装菜,但是盘子不能装汤的道理,虽然double类型可以接收int类型数据,但是一般不建议这样操作)
double c = 10.5;
c = 10;
print(c);//10.0
//关于数值基础运算符:+(加)、-(减)、*(乘)、/(除)、%(取余)
print(a + b); //20.5
print(a - b); //0.5
print(a * b); //105.0
print(a / b); //1.05
print(a % b); //0.5
//取整运算 ~/,表示只取整数部分,舍去小数部分
print(a ~/ b);// 1
//关于数值类型常见的函数处理
print(b.isEven);//是否是偶数,返回bool类型数据,是偶数返回true,不是偶数返回false,注意要用int类型定义的数值才可用该函数,使用num类型会报错
//print(a.isEven); //a是num类型定义,报错:The getter 'isEven' isn't defined for the type 'num'.
print(b.isOdd);//是否是奇数,返回bool类型数据,是奇数返回true,不是奇数返回false,注意要用int类型定义的数值才可用该函数,使用num类型会报错
//求绝对值
int d = -10;
print(d.abs()); // 10
//四舍五入
double e = 3.8;
print(e.round()); // 4
//向上取整
double f = 3.1;
print(e.ceil()); //4
//向下取整
double g = 3.9;
print(e.floor()); //3
//double类型转int类型(精度丢失,非安全操作)
print(f.toInt()); //3
print(g.toInt()); //3
//int类型转double类型(安全操作)
int h = 8;
print(h.toDouble()); //8.0
常用的数值类型的运算操作和常见函数操作基本就是这些,后续运用中遇到再细说。
- bool类型
bool是Dart中布尔类型,该类型的数据在Dart中只表示两个结果:true或false,是后续进行编写代码逻辑的重要类型
//true和false
bool flag = true;
print(flat);//true
flag = false;
print(flat);//false
- String类型
String在Dart中表示字符串类型,在Dart中没有char类型,字符也是用String类型表示。
//定义字符串类型变量
String str1 = "英雄"; //也可以用单引号''
print(str1);//英雄
String str2 = '联盟';
print(str2);//联盟
//字符串拼接
String str3 = str1 + str2;
print(str3);//英雄联盟
//或者通过$符号去获取变量的值
print("$str1$str2");//英雄联盟
//多行字符串定义,保持原来字符串的格式输出,使用三引号包裹(单引号和双引号都可以)
String str4 = """
天门中断楚江开,
碧水东流至此回。
""";
/*打印结果:
天门中断楚江开,
碧水东流至此回。
*/
//转义字符串
String str5 = "王者\n荣耀";
print(str5);//输出结果如下:
/*
王者
荣耀
*/
//如果需要输出字符串中转义字符,使用r(必须是小写r,raw的缩写,原始的意思)
String str6 = r"王者\n荣耀";
print(str6);// 王者\n荣耀
//复制字符串
String str7 = "加油";
print(str7 * 5); //油加油加油加油加油
//比较字符串是否相等,返回bool类型值,相等返回ture,不相等返回false
print(str6 == str7); //false
//获取字符串中字符的个数(也叫字符串长度)
print(str7.length); // 2
//判断字符串长度是否为0(空字符串,注意这里的空不是null)
String str8 = "";
print(str8.isEmpty); //长度为0返回ture,长度不为0返回false
print(str8.isNotEmpty); //长度为0返回false,长度不为0返回ture
//判断字符串中是否包含某个字符或者某个子字符串,格式:原字符串.contains(子字符串),原字符串包含子字符串返回true,不包含返回false
String str9 = "疯狂星期四,可以v我50吗";
print(str9.contains("50")); //true
print(str9.contains("KFC")); //false
//查找某个子字符串的位置
print(str9.indexOf("50")); //10
//注意:当字符串中有相同的子字符串,查找位置时,会返回第一个匹配的子字符串的下标
str9 = "疯狂星期四,可以v我50吗,只要50块";
print(str9.indexOf("50")); //10
//获取某个子字符串在原字符串中最后的下标
print(str9.lastIndexOf("50")); //16
//截取原字符串中某一段字符串并返回,格式:原字符串.substring(开始下标,截止下标),返回从原始字符串指定开始下标位置,到指定截止下标位置的子字符串,注意:取值到截止下标的前一位,截止下标位置 <= 原字符串长度
String str10 = "要什么自行车啊";
print(str10.substring(3, 6));//自行车
//判断字符串的开头和结尾
String str11 = "正义,要么靠法律,要么靠武力!";
print(str11.startsWith("正义")); //true
print(str11.endsWith("!")); //true
//将字符串所有字符转大写字母
String str12 = "You jump, I jump.";
print(str12.toUpperCase()); // YOU JUMP, I JUMP.
//将字符串所有字符转小写字母
print(str12.toLowerCase()); // you jump, i jump.
//去除字符串左右的空格
String str13 = " 无形之刃,最为致命。 ";
print(str13.trim()); //无形之刃,最为致命。
//只去除字符串左侧的空格
print(str13.trimLeft()); //形之刃,最为致命。(这里有空格)
//只去除字符串右侧的空格
print(str13.trimRight());// 无形之刃,最为致命。
//拆分(切割)字符串,注意:作为切割符的子字符串,不会被放到切割后的列表中
String str14 = "不要害怕未知的事物。";
List strList = str14.split("害怕"); //List表示列表,可以理解为数组,后面会讲到
print(strList); // [不要, 未知的事物。]
//替换原字符串中的子字符串
String str15 = "May the Force be with you";
//将字符串中所有的e都替换成a
print(str15.replaceAll('e', 'a'));//May tha Forca ba with you
//替换原字符串中第一个符合的子字符串
print(str15.replaceFirst('e', 'a'));//May tha Force be with you
关于字符串的常见处理操作大致这些,后续再遇到我们再详细介绍。
- List类型
List是Dart中的列表类型,在Dart中没有数组类型,List类型可以当做数组类型来使用。
//定义一个任意List变量(也叫List对象),List可以用var代替:var list1 = [......];
List list1 = [1, 2, 3, '暗影岛', false];//不限定长度,不限定类型的列表
print(list1); //[1, 2, 3, 暗影岛, false]
//如果要定义只能存放特定类型的列表,格式List<数据类型> 变量名字,这里List不能用var;
List<String> list2 = ["比尔吉沃特","黑色玫瑰","卡拉曼达"];//限定了类型,没有限定长度的列表
print(list2); //[比尔吉沃特, 黑色玫瑰, 卡拉曼达]
//要获取List中存放元素(数据)的个数,也叫列表的长度
print(list2.length); // 3
//获取List中某个元素
print(list2[0]); //比尔吉沃特
//修改List中某个元素的值
list2[1] = "德玛西亚";
print(list2); // [比尔吉沃特, 德玛西亚, 卡拉曼达]
//往List中新增一个元素,注意:添加在列表的末尾
list2.add("钢铁烈阳");
print(list2); // [比尔吉沃特, 德玛西亚, 卡拉曼达, 钢铁烈阳]
//在任意下标位置插入单个元素, 格式:列表对象.insert(要插入的下标位置,要插入的元素),注意:要插入的下标位置<=列表的长度
list2.insert(0, "祖安");
print(list2); // [祖安, 比尔吉沃特, 德玛西亚, 卡拉曼达, 钢铁烈阳]
//在任意位置插入一组元素(另外一个列表),格式:列表对象.insertAll()
list2.insertAll(1, ["战争学院", "班德尔城"]);
print(list2); //[祖安, 战争学院, 班德尔城, 比尔吉沃特, 德玛西亚, 卡拉曼达, 钢铁烈阳]
//在列表末尾添加(拼接)另外一个列表
list2.addAll(["艾欧尼亚", "诺克萨斯"]);
print(list2); //[祖安, 战争学院, 班德尔城, 比尔吉沃特, 德玛西亚, 卡拉曼达, 钢铁烈阳, 艾欧尼亚, 诺克萨斯]
//移除List中某个元素
list2.remove("德玛西亚");
print(list2); //[祖安, 战争学院, 班德尔城, 比尔吉沃特, 卡拉曼达, 钢铁烈阳, 艾欧尼亚, 诺克萨斯]
list2.removeAt(0);//0表示下标为0的元素,列表中第一个元素的下标为0,第二个下标为1,依次类推,最后一个元素的下标为列表长度-1,注意用下标移除元素,下标不能超过列表长度-1
print(list2); //[战争学院, 班德尔城, 比尔吉沃特, 卡拉曼达, 钢铁烈阳, 艾欧尼亚, 诺克萨斯]
//移除列表中最后一个元素
list2.removeLast();
print(list2);//[战争学院, 班德尔城, 比尔吉沃特, 卡拉曼达, 钢铁烈阳, 艾欧尼亚]
//移除列表中一段元素,格式:列表对象.removeRange(开始下标,结束下标),注意:开始下标<列表长度,结束下标<=列表长度,结束下标所在元素不会被移除
list2.removeRange(0, 2);//表示移除下标为:0、1的元素
print(list2); //[比尔吉沃特, 卡拉曼达, 钢铁烈阳, 艾欧尼亚]
//移除符合某个特定条件的列表元素,注意:removeWhere(匿名函数),会面会详细介绍,这里先做了解
list2.removeWhere((element) => element == "卡拉曼达");//移除列表中元素等于"卡拉曼达"的元素
print(list2); //[比尔吉沃特, 钢铁烈阳, 艾欧尼亚]
//移除列表中所有元素
//list2.clear();
//print(list2);//[]
//用某个值替换指定索引范围内的所有元素,格式:列表对象.fillRange(开始下标,结束下标,新元素),注意:结束下标对应元素不会被替换
list2.fillRange(0, 2, "LOL");
print(list2);//[LOL, LOL, 艾欧尼亚]
//用一组值(列表)替换指定索引范围内的所有元素,格式:列表对象.replaceRange(开始下标,结束下标,新列表),注意:结束下标对应元素不会被替换
list2.replaceRange(0, 2, ["英雄联盟", "拳头公司"]);
print(list2); // [英雄联盟, 拳头公司, 艾欧尼亚]
//替换列表中特定范围的值,格式:setRange(开始下标,结束下标,替换列表),注意:替换列表的长度和"结束下标-开始下标"的值保持一致,否则会报错,这也是和replaceRange的区别
list2.setRange(0, 2, ["LOL", "LOL"]);
print(list2); //[LOL, LOL, 艾欧尼亚]
//从指定下标开始,用新列表逐一替换原来列表内容,格式:列表对象.setAll(开始下标,新列表),注意:新列表的长度+开始下标 <= 原来列表的长度,否则会报错
list2.setAll(0, ["德玛西亚"]);
print(list2); //[德玛西亚, LOL, 艾欧尼亚]
//查询列表中指定下标位置的元素,返回对应的列表元素
print(list2.elementAt(0));//德玛西亚
//获取指定元素多对应的下标,返回对应元素的下标
print(list2.indexOf("德玛西亚")); //0
//判断列表中是否包含某个元素,包含返回true,不包含返回false
print(list2.contains("LOL")); //true
print(list2.contains("lol")); //false
//遍历元素中每个元素,是否符合已给定的条件,符合条件返回true,不符合条件返回false
print(list2.every((element) => element == "LOL"));//false,这里判断是否所有元素都等于LOL
//获取列表中指定起始下标的元素,格式:列表对象.getRange(开始下标,结束下标),注意:结束下标对应元素不会返回
print(list2.getRange(0, 2));//(德玛西亚, LOL)
//从指定下标开始到指定下标结束,截取列表中一段元素,格式:列表对象.sublist(开始下标,结束下标),注意:结束下标对应元素不会被截取
print(list2.sublist(1, 3));
//定义一个固定长度的列表
List list3 = List.filled(4, "盖伦");
print('$list3'); // [盖伦, 盖伦, 盖伦, 盖伦]
//固定长度列表不可以添加元素
list3.add("卡特琳娜");// Unsupported operation: Cannot add to a fixed-length list
//固定长度列表不可以移除元素
list3.remove("盖伦");// Unsupported operation: Cannot remove from a fixed-length list
//固定长度列表可以修改元素的值
list3[1] = "卡特琳娜";
print('$list3'); //[盖伦, 卡特琳娜, 盖伦, 盖伦]
//关于List还有一些其他操作方法,后续用到再进行详细介绍
/*
forEach 遍历列表中的元素
map 遍历列表中的所有元素,可以对元素进行处理,并返回新的列表
toSet 将List转换为Set,可得到去重后的元素
asMap 将List转换为Map,key为原数组的索引,value为原数组的元素
sort 列表排序(原列表发生改变)
join 用指定字符连接列表中每个元素,返回String类型数据
*/
关于List的操作还有很多,比如查找某个元素的下标、列表排序、列表打乱、列表遍历、列表截取、List转Map等,后续我们都会陆续介绍到。
- Map类型
Map是Dart中的映射类型,即键值对类型(iOS中叫字典类型)。数据格式{key1:value1,key2:value2,......},这里的key和value可以是任何类型的对象。注意:在一个Map类型的对象中,每个键(key)是唯一的,value可以出现多次。映射类型是动态集合。即Maps可以在运行时增长和缩小,dart:core库中的Map类提供了相同的支持。
//定义一个任意Map变量(也叫Map对象),Map可以用var代替:var map1 = {......};
Map map1 = {'hero': '盖伦', 1: "闪现", true: 2};
print(map1);//{hero: 盖伦, 1: 闪现, true: 2}
//定义一个指定了key的类型和value类型的变量
Map<String, int> map2 = {"a": 1, "b": 2, "c": 2};
print(map2); // {a: 1, b: 2, c: 2}
//往map中添加一组数据
map2["d"] = 3;
print(map2); // {a: 1, b: 2, c: 2, d: 3}
//修改map中已有的数据
map2["a"] = 4;
print(map2); // {a: 4, b: 2, c: 2, d: 3}
//获取map中所有的key
print(map2.keys); //(a, b, c, d)
//获取map中所有的value
print(map2.values); //(4, 2, 2, 3)
//可以使用new关键字创建一个map变量
var map3 = new Map(); //Dart2.0后,new可以省略,即写成:var map3 = Map();
print(map3); // {}
//创建一个不可被修改的Map变量
var map4 =const {"name": "张三"};//或写成:const map4 = {"name": "张三"};
//不可以往const修饰的Map变量中添加元素
map4["gender"] = "男"; //Unsupported operation: Cannot modify unmodifiable map
//从已有Map对象创建一个新的Map对象,新Map对象中包含原有Map对象所有元素
Map map5 = {"first": "1", "second": "2"};
Map map6 = Map.castFrom(map5);
print(map6);//{first: 1, second: 2}
//获取Map中所有元素的个数
print(map6.length);//2
//判断Map对象是否为空,即Map对象中的元素个数是否为0
print(map6.isEmpty);//false,为空返回ture,不为空返回false
print(map6.isNotEmpty);//true,为空返回false,不为空返回true
//获取Map对象迭代的键值对集合
print(map6.entries); //(MapEntry(first: 1), MapEntry(second: 2))
//对Map对象中指定的key的value进行修改
Map map7 = {"hero": "卡特琳娜", "skill": "弹射之刃"};
print(map7);//{hero: 卡特琳娜, skill: 弹射之刃}
//注意:update中的key必须是原有Map对象已具备的key
map7.update("skill", (value) => value = "伺机待发");
print(map7);//{hero: 卡特琳娜, skill: 伺机待发}
//如果更新Map对象中不具备的key对应的value,会报错
map7.update("price", (value) => value = 8800);
print(map7);//Invalid argument (key): Key not in map.: "price"
//如果key不具备,可以使用ifAbsent解决,可以自动添加要更新的key
map7.update("price", (value) => value = 8800, ifAbsent: () => (8800));
print(map7); // {hero: 卡特琳娜, skill: 伺机待发, price: 8800}
//对Map对象中的元素进行批量修改
Map<String, int> map8 = {"first": 1, "second": 2, "third": 3};
print(map8); // {first: 1, second: 2, third: 3}
map8.updateAll((key, value) => value * 2);
print(map8); // {first: 2, second: 4, third: 6}
//移除Map对象中特定的key-value对
Map<String, int> map9 = {"first": 1, "second": 2, "third": 3};
print(map9); //{first: 1, second: 2, third: 3}
map9.remove("second");
print(map9); //{first: 1, third: 3}
//批量移除满足条件的所有key-value对
Map<String, int> map10 = {"first": 1, "second": 2, "third": 3, "four": 4};
print(map10); // {first: 1, second: 2, third: 3, four: 4}
map10.removeWhere((key, value) => value > 2);
print(map10); // {first: 1, second: 2}
//清空Map对象
map10.clear();
print(map10); // {}
//判断Map对象中是否包含特定的key,包含就返回true,不包含返回false
print(map10.containsKey("first")); //true
//判断Map对象中是否包含特定的value,包含就返回true,不包含返回false
print(map10.containsValue("2")); // false,map10中value包含2,不包含"2"
//遍历Map对象中所有元素
Map<String, int> map11 = {"first": 1, "second": 2, "third": 3, "four": 4};
map11.forEach((key, value) {
//判断如果value>2,就打印value,否则就打印0,注意:?: 为三目运算符,?前面表达式成立,就返回:左侧的值,否则返回:右侧的值
print(value > 2 ? value : 0); // 0 0 3 4
});
//合并两个Map对象,注意要合并的两个Map对象的key和value类型要一致,否则报错
Map<String, int> map12 = {"first": 1, "second": 2};
print(map12); // {first: 1, second: 2}
Map<String, int> tempMap1 = {"third": 3, "four": 4};
map12.addAll(tempMap1);
print(map12); // {first: 1, second: 2, third: 3, four: 4}
//注意:合并过程中,如果两个Map对象中有相同的key,value值后者覆盖前者,如果两个Map中key都不相同,则是后者添加到原有Map对象中
Map<String, int> tempMap2 = {"third": 100, "five": 5};
map12.addAll(tempMap2);
print(map12); // {first: 1, second: 2, third: 100, four: 4, five: 5}
//还有一种合并Map对象合并方式(暂没发现addEntries和addAll的区别🤦🏻♀️,如果有知道的大佬,欢迎指教)
Map<String, int> map13 = {"first": 1, "second": 2};
print(map13); // {first: 1, second: 2}
Map<String, int> tempMap = {"third": 3, "four": 4};
map13.addEntries(tempMap.entries);
print(map13); // {first: 1, second: 2, third: 3, four: 4}
//获取Map对象中特定key的值,如果key存在就返回对应的value,如果不存在就添加对应的key-value
Map<String, int> map14 = {"first": 1, "second": 2};
int result1 = map14.putIfAbsent("first", () => (2));
print(result1); // 存在first的key,返回对应的value值1,存储到result1中
int result2 = map14.putIfAbsent("third", () => (3));
print(result2); // 不存在third的key,返回3,存储到result2中
print(map14); //{first: 1, second: 2, third: 3},将对应的key-value添加到Map对象中
关于Map的常见操作基本是这些,后续如果有遇到其他,再进行解析。特殊注意点:Map里面的key不能相同,value可以相同,value可以为空字符串或者null
- Set类型
Set是Dart中的集合类型,它的特点是去除重复,Set是没有顺序且不能重复的集合,所以不能通过下标索引去获取Set中的元素。
Set s = new Set();
s.add('王者');
s.add('荣耀');
s.add('荣耀'); //添加重复元素是无效的
print(s); // {王者, 荣耀}
//可以将Set转成List类型
List sList = s.toList();
print(sList); // 转换List类型 [王者, 荣耀]
//可快速实现对列表元素去重
List myList = ["亚瑟", "赵云", "亚瑟", "百里守约", "亚瑟", "百里玄策"];
print("去重前:$myList"); // 去重前:[亚瑟, 赵云, 亚瑟, 百里守约, 亚瑟, 百里玄策]
Set mySet = new Set();
mySet.addAll(myList);
myList = mySet.toList();
print("去重后:$myList"); // 去重后:[亚瑟, 赵云, 百里守约, 百里玄策]
- dynamic类型
dynamic表示动态类型,该类型变量可存储任意数据。该类型的变量在编译阶段不会做类型检查,在运行时才会根据赋值进行类型确定,使用起来较方便,但是存在一定隐患,使用需谨慎。
//runtimeType可以获取变量的运行时数据类型
dynamic temp1 = 10; // 编译时不会确定数据类型,但是运行时会推断
print(temp1.runtimeType); // int
temp1 = "flutter";
print(temp1); // flutter
print(temp1.runtimeType); // String
var temp2;
temp2 = 10;
print(temp2.runtimeType); // int
temp2 = "dart";
print(temp2.runtimeType); // int
print(temp2); //dart
Object temp3 = 'swift';
print(temp3.runtimeType); // String
print(temp3);
temp3 = 10;
print(temp3.runtimeType); // int
print(temp3); // 10
var:定义的变量可以赋值任意值。但是变量一旦赋值,变量类型就会确定,不能再赋其他类型值.dynamic泛型:定义的变量可以赋值任意值,在后期依然可以赋值不同数据类型值。Object:是所有对象的基类,所有类型都继承自Object(包括Function和Null),所以任何类型的数据都可以赋值给Object类型变量。var初始化确定类型后不可更改类型,Object以及dynamic可以更改类型。 而dynamic与Object相同之处在于Object编译阶段检查类型, 而dynamic编译阶段不检查类型。
- Runes类型 :不过多介绍,后续感兴趣可以自己研究
- Symbol类型:不过多介绍,后续感兴趣可以自己研究
2. Dart中的枚举类型
- 枚举: 就是列举所有的可能值, 每一种可能值我们叫做枚举值
- 作用: 将人能够看懂的标识符与计算机能够识别的数字建立起来对应的关系.
- 目的: 提高程序的可读性, 代码易于维护
- 注意:枚举的关键字
enum,可用来代替一些字面量、常量
//定义季节的枚举
enum SeasonType {
spring,
summer,
autumn,
winter,
}
main() {
//可通过index获取值的索引
print(SeasonType.spring.index); //0
print(SeasonType.summer.index); //1
print(SeasonType.autumn.index); //2
print(SeasonType.winter.index); //3
print(SeasonType.values); // [SeasonType.spring, SeasonType.summer, SeasonType.autumn, SeasonType.winter]
//values可以获取所有枚举值,返回List类型列表
List<SeasonType> seasonList = SeasonType.values;
print(seasonList);// [SeasonType.spring, SeasonType.summer, SeasonType.autumn, SeasonType.winter]
//列表对象.forEach可以遍历列表中元素,枚举对象.name可以获取定义的枚举名称
seasonList.forEach((element) {
print("元素:${element.name},下标:${element.index}");
});
/*
输出结果:
元素:spring,下标:0
元素:summer,下标:1
元素:autumn,下标:2
元素:winter,下标:3
*/
}