内容简介:总的来看Dart的常见的数据类型有下面8种:num、int和double都是Dart种的类,也就是说它是对象级别的,s所以他们的默认值为null。这不同于Java的基本数据类型。布尔类型作为判断的标识,活跃在各大语言中的逻辑判断中,它只有true和false两种选择。这里注意关键字是
总的来看Dart的常见的数据类型有下面8种:
1.1.数字类型
num、int和double都是Dart种的类,也就是说它是对象级别的,s所以他们的默认值为null。这不同于 Java 的基本数据类型。
main(){ num age = 18;//num数据类型 int height =180;//int整型 double weight=62.5;//double 浮点型 print(height/weight is double);//true print(height*age is double);//false print(age/height is double);//true } 复制代码
1.2.布尔类型
布尔类型作为判断的标识,活跃在各大语言中的逻辑判断中,它只有true和false两种选择。这里注意关键字是 bool
,而非Java中的 boolean
。
bool isMan = true; bool isMarried = false; 复制代码
1.3.字符串类型
字符串是一种语言不可获取的部分,Dart也不例外。它支持单引号、双引号、以及三引号。需要注意的是单引号中的单引号需要转义,三引号中的字符内容会原样输出。
String name = '张风捷特烈';//支持单引号 String proverbs ="'海的彼岸有我未曾见证的风采'";//支持双引号 String poem=""" //支持三引号 >《零境》 ----张风捷特烈 飘缥兮飞烟浮定, 渺缈兮皓月风清。 纷纷兮初心复始, 繁繁兮万绪归零。 2017.11.7 改 <br/> """; print('${name}\n$proverbs\n$poem');//支持字符串中使用变量 复制代码
1.4.列表类型
List作为一个同类多元素的容器,也是每种语言必备。Dart中的List作为一个类存在,可以当做可操作的数组来对待,起始索引为0。其他语言中对于数组的操作,Dart中基本都有相关的API。
List<String> languages = ['Java', 'Dart', 'Python', 'C++', 'Kotlin']; print(languages[0]); //Java languages.add("JavaScript");//添加元素 复制代码
1.5.集合类型
Set作为一个盛放不含重复元素的无序多元素容器,如果添加一个已经存在的元素,是无法添加成功的。所以它没有索引。但有很多方法可以对集合进行操作
Set<String> languages = {'Java', 'Dart', 'Python', 'C++', 'Kotlin',"Java"}; print(languages);//{Java, Dart, Python, C++, Kotlin} print(languages.add('Java'));//false print(languages.add('JavaScript'));//true 复制代码
1.6.Map类型
Map为若干个键值对的容器,想用映射之名。其中一个Map对象中的键不能重复,值是可以重复的。
Map<int, String> map = {1: 'one', 2: 'two', 3: 'three'}; print(map[3]);//three map[4] = 'four'; print(map.length);//4 复制代码
1.7.Runes
这是一个Dart中的新名词,首先看他的地位:它是一个类,继承自Iterable,也就是说它是一个可比遍历的int型元素组合体。
在String类源码的第一行有这么一句话: A sequence of UTF-16 code units.
说明Dart中字符串的编码是UTF-16,查看一个字符串的UTF-16可以用 xxx.codeUnits
,可以获得一个int数组。
String dart ="Dart"; print(dart.codeUnits);//[68, 97, 114, 116] 复制代码
看一个恶魔的emoji :imp:,对应的Unicode为 \u{1f47f}
,看一下他的UTF-16码
var evil = '\u{1f47f}'; print(evil);//:imp: print(evil.codeUnits);//[55357, 56447] 复制代码
通过 xxx.runes
方法,可以获得一个Runes对象,可以看出一个emoji是和一个Runes元素对应的,而不像UTF-16需要两个码联合起来才可以表示。这就有一个好处:我们可以将emoji当做可迭代的元素进行处理。
var evil = '\u{1f47f}\u{1f47a}\u{1f47b}'; print(evil);//:imp::japanese_goblin::ghost: print(evil.codeUnits);//[55357, 56447, 55357, 56442, 55357, 56443] print(evil.runes);//(128127, 128122, 128123) 复制代码
比如对Runes中的元素做个map操作
Runes input = Runes('\u2695\u{1f47a}\u{1f34b}\u2653\u{1f46d}\u{1f34e}\u2694\u{1f470}\u{1f349}'); print(input);//(9877, 128127, 127823, 9861, 128111, 127823, 9877, 128127, 127823) print(String.fromCharCodes(input));//⚕:japanese_goblin::lemon::pisces::two_women_holding_hands::apple:⚔:bride_with_veil::watermelon: print(String.fromCharCodes(input.map((e){ return e-5; })));//⚐:older_woman::eggplant::libra::man::watermelon:⚏:couple::mushroom: 复制代码
1.8.Symbols
首先毋庸置疑Symbols也是一个类,从名称上来看是一个标志,用起来也比较特殊。
总的来说它可以标识出一个字符串,然后通过MirrorSystem.getName来获取到。好处是这个标志字符串无法磨灭,即使混淆了代码,也可以获得。
一般用于反射时类名的处理,但是Flutter中是 禁止用反射
的,所以没有 dart:mirrors
包。这个了解一下,看到认识即可。
Symbol className = #Person; print(className);//Symbol("Person") MirrorSystem.getName(className); 复制代码
关于具体的API操作,这里就不做过多阐述,总体来说和主流语言都是一致的,以后再代码中用到也会提一下。
2.Dart中的变量与常量
Dart 作为一名新时代的后起之秀,var自然不能少。Dart语言中对象的类型是可以自动推导的。也就是说,上面的代码在声明变量类型时,都可以用一个var关键字解决。
2.1:var关键字的使用
var age = 18; var isMan = true; var name = '张风捷特烈'; var languages = ['Java', 'Dart', 'Python', 'C++', 'Kotlin']; var languages2 = {'Java', 'Dart', 'Python', 'C++', 'Kotlin',"Java"}; var map = {1: 'one', 2: 'two', 3: 'three'}; var className = #Person; 复制代码
2.2:var的注意点
如果只是用var声明变量,该变量之后是可以修改数据类型的
var who; who="what"; print(who is String);//true who=10; print(who is int);//true 复制代码
如果声明的同时取赋值,那么该对象的类型就是固定的,不可修改
var who="what"; print(who is String);//true who=10;//此处报错 print(who is int);//true 复制代码
下面一幅图可以很好地说明原因:未赋值是,var声明的变量类型为dynamic(动态的),dynamic也是一个关键字
dynamic d = 20; 复制代码
2.3:常量的定义
如果一个变量你以后不打算修改,可以使用 final 或者 const进行修饰,当你试图修改它的值,就会报错。
final PI = 3.14159265; PI=4;// ERROR: 'PI', a final variable, can only be set once. const Pi = 3.14159265; Pi=4;// ERROR: Constant variables can't be assigned a value. 复制代码
2.4:const和final的区别
一个 final 变量只能赋值一次:它的值可以在运行时获取
一个 const 变量是编译时常量:码还没有运行时我们就知道它声明变量的值
如下,同样是当前时间,final修饰的f对象是正确的,但const修饰的c是错误的,原因是final可以在运行时对变量初始化,但const不行。
final f = DateTime.now(); // OK const c = DateTime.now(); // ERROR Const variables must be initialized with a constant value. 复制代码
3.运算符
常见运算符一览
3.1:算术运算符
四则运算
print(1 + 2);//3 加 print(1 - 2);//-1 减 print(1 * 2);//2 乘 print(1 / 2);//0.5 除 print(10 % 3);//1 余 print(10 ~/ 3);//3 商 复制代码
自加自减
---->[情况1:i++]---- int i=3; var a=i++;//执行赋值后i才自加,故a=3 print('a=$a,i=$i');//a=3,i=4 ---->[情况2:++i]---- int i=3; var a=++i;//执行赋值前i已经自加,故a=4 print('a=$a,i=$i');//a=4,i=4 ---->[情况3:i--]---- int i=3; var a=i--;//执行赋值后i才自减,故a=3 print('a=$a,i=$i');//a=3,i=2 ---->[情况4:--i]---- int i=3; var a=--i;//执行赋值前i已经自减,故a=2 print('a=$a,i=$i');//a=2,i=2 复制代码
3.2:关系运算符
print(1 > 2); //false 大于 print(1 < 2); //true 小于 print(1 == 2); //false 等于 print(1 != 2); //true 不等 print(10 >= 3); //true 大于等于 print(10 <= 3); //false 小于等于 复制代码
3.3:位运算符
拿两个数来说明一下位运算:a=1705和b=17589
位与:& 两个都是1为1 位或:| 只要有1就是1 位非:~ 全取反 位都不一样为1 左位移:<< 右位移:>> 例子:c = a & b 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 & 0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 --------------------------- 0000 0000 0000 0000 0000 0100 1010 0001 [c] 0x000004a1 1185 例子:d = a | b 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 | 0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 --------------------------- 0000 0000 0000 0000 0100 0110 1011 1101 [d] 0x000046bd 18109 例子:e = ~a 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 ~ 1111 1111 1111 1111 1111 1001 0101 0110 [e] 0xfffff956 -1706 例子:f = a ^ b 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 ^ 0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 --------------------------- 0000 0000 0000 0000 0100 0010 0001 1100 [f] 0x0000421c 16924 例子:g = a << 4 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 0000 0000 0000 0000 0000 0110 1010 1001 <---移位 0000 0000 0000 0000 0110 1010 1001 0000 [g] 0x00006a90 27280=1705*2^4 例子:h = a >> 4 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 0000 0000 0000 0000 0000 0110 1010 1001 <---移位 0000 0000 0000 0000 0000 0000 0110 1010 [g] 0x0000006a 27280=106 复制代码
3.4:逻辑运算符
下面的代码表示:年龄大于22或者身高大于160的女性可以进入。
bool enter(int age, int height, bool isMan) { return (age > 18 || height > 140) && !isMan; } 复制代码
3.5:赋值运算符
上图中的下面一行都是运算符和等号的组合,其中
a += b 等价于 a = a + b 复制代码
其他运算符依此类推,这里主要讲一下比较特别 ??=
,当变量的值为null时,执行赋值语句,否则不赋值
---->[情况1:b值为null]---- var a = 20; var b; b ??= a; print(b);//20 ---->[情况2:b值不为null]---- var a = 20; var b = 2; b ??= a; print(b);//2 复制代码
3.6:条件表达式
三元运算符:条件成立执行前者,否则,执行后者
var height =130; var pay = (height>120) ? 200:100; print(pay);//200 复制代码
??运算符:前表达式值为null则取后者。否则,后表达式不会被执行
---->[情况1:b值为null]---- var a = 20; var b; var c=b ?? a++; print('a=$a,c=$c');//a=21,c=20 ---->[情况1:b值为null]---- var a = 20; var b = 2; var c = b ?? a++; print('a=$a,c=$c'); //a=20,c=2 复制代码
4.Dart中的函数
Dart中,一个函数的基本组成如下:
4.1:基本使用
两个数相加
double add(double a,double b){ return a+b; } 调用:add(10,20);//30 复制代码
4.2:可选参数+默认值
两个数相加,并且可以打个折扣
double add(double a,double b,[double discount=1.0]){ return (a+b)*discount; } 调用:add(10,20,0.7);//21 复制代码
4.3:属性型参数
将参数和一个key对应起来,非常方便和清晰的传参模式
double add(double a,double b,{double discount=1.0,double c=0,double d =0}){ return (a+b+c+d)*discount; } 调用:add(10, 20,discount: 0.7,c: 100);//91.0 复制代码
4.4:函数参数
值得一说的是,函数本身也是一个对象,可以作为参数传入。
double add(double a,double b,deal){ return deal(a)+deal(b); } 调用: var fun = (double i) { return i * i; }; print(add(3, 4, fun));//求两数的平方和 复制代码
4.5:函数简写
var fun = (double i) { return i * i; }; 可以简写为: var fun = (i) { return i * i; }; 进一步可以简写为: var fun = (i)=> i * i; 复制代码
这样的话,初始代码的开始应该能看懂了吧
void main() => runApp(MyApp()); 它相当于: void main() { return runApp(MyApp()); } 复制代码
5.Dart 流程控制
老生常谈了,写个方法示意一下。
5.1: if...else
if(进入条件){执行体}else{执行体}
double sale(height) { if(height<=0){//if可以单独使用 return 0; } var price = 100;//票价 var disCount = 1.0;//折扣 if (height > 140) {//if可以结合else if使用 disCount=0;//身高140下免费 }else if(height<160){ disCount=0.7;//身高160下七折 } return price * disCount; } 复制代码
5.2:for循环
for(初始变量;退出条件;每次循环执行完变量的操作){执行体}
for(var count=0;count<10;count++){ print("count:$count"); } 复制代码
5.3:while循环
while(进入条件){执行体}
var count=0; while(count<10){ print("count:$count"); count++; } 复制代码
5.4:do...while循环
do{执行体}while(进入条件)
var count=0; do{ print("count:$count"); count++; }while(count<10); 复制代码
5.5:break和continue
用于循环体的控制。break直接退出循环;continue进入下次循环
---->[break情景]---- for(var count=0;count<10;count++){ if(count%3==2){ break;//直接跳出循环 } print("count:$count");//打印了0,1 } ---->[continue情景]---- for(var count=0;count<10;count++){ if(count%3==2){ continue;//跳出本次循环,将进入下次循环 } print("count:$count");//打印了0,1,3,4,6,7,9 } 复制代码
5.6:switch和case
在非常多的分支时,可以用switch和case处理,比if...else简洁
var mark='A'; var evaluation; switch(mark){ case'A': evaluation="优秀"; break; case'B': evaluation="良好"; break; case'C': evaluation="普通"; break; case'D': evaluation="较差"; break; case'E': evaluation="极差"; } print(evaluation);//优秀 复制代码
以上所述就是小编给大家介绍的《Flutter之旅:Dart的基础语法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。