Dart的所有東西都是對(duì)象吊骤,包括數(shù)字,函數(shù)等亏较。
它們都繼承自O(shè)bject莺褒,默認(rèn)是都是null(包括數(shù)字),所以數(shù)字雪情,字符串都可以調(diào)用各種方法遵岩。
本文主要講解:Dart語(yǔ)法知識(shí)包括數(shù)據(jù)類型、變量常量巡通、集合尘执、流程控制、運(yùn)算宴凉、異常誊锭、函數(shù)、面向?qū)ο?/b>
一弥锄、Hello Dart
這是第一個(gè)Hello Dart程序丧靡,很多程序入口都是從main函數(shù)開始,所以dart也不例外籽暇,一起來(lái)看下百變的main函數(shù)
//main標(biāo)準(zhǔn)寫法
voidmain() {
print('Hello World!');//注意: Dart和Java一樣表達(dá)式以分號(hào)結(jié)尾温治,寫習(xí)慣Kotlin的小伙伴需要注意了, 這可能是你從Kotlin轉(zhuǎn)Dart最大不適之一。
}
//dart中void類型图仓,作為函數(shù)返回值類型可以省略
main() {
print('Hello World!');
}
//如果函數(shù)內(nèi)部只有一個(gè)表達(dá)式罐盔,可以省略大括號(hào),使用"=>"箭頭函數(shù);
//而對(duì)于Kotlin則是如果只有一個(gè)表達(dá)式救崔,可以省略大括號(hào)惶看,使用"="連接捏顺,類似 fun main(args: Array) = println('Hello World!')
voidmain()=>print('Hello World!');
//最簡(jiǎn)寫形式
main()=>print('Hello World!');
二、數(shù)據(jù)類型
在dart中的一切皆是對(duì)象纬黎,包括數(shù)字幅骄、布爾值、函數(shù)等本今,它們和Java一樣都繼承于Object, 所以它們的默認(rèn)值也就是null. 在dart主要有: 布爾類型bool拆座、數(shù)字類型num(數(shù)字類型又分為int,double冠息,并且兩者父類都是num)挪凑、字符串類型String、集合類型(List, Set, Map)逛艰、Runes類和Symbols類型(后兩個(gè)用的并不太多)
1躏碳、布爾類型(bool)
在dart中和C語(yǔ)言一樣都是使用bool來(lái)聲明一個(gè)布爾類型變量或常量,而在Kotlin則是使用Boolean來(lái)聲明散怖,但是一致的是它對(duì)應(yīng)的值只有兩個(gè)true和false.
main() {
boolisClosed=true;//注意菇绵,dart還是和Java類似的 [類型][變量名]方式聲明,這個(gè)和Kotlin的 [變量名]:[類型]不一樣.
boolisOpened=false;
}
2镇眷、數(shù)字類型(num咬最、int、double)
在dart中num欠动、int永乌、double都是類,然后int、double都繼承num抽象類翁垂,這點(diǎn)和Kotlin很類似铆遭,在Kotlin中Number、Int沿猜、Double都是類枚荣,然后Int、Double都繼承于Number. 注意啼肩,但是在dart中沒有float, short, long類型

main() {
doublepi=3.141592653;
intwidth=200;
intheight=300;
print(width/height);//注意:這里和Kotlin橄妆、Java都不一樣,兩個(gè)int類型相除是double類型小數(shù)祈坠,而不是整除后的整數(shù)害碾。
print(width~/height);//注意: 這才是dart整除正確姿勢(shì)
}
此外和Java、Kotlin一樣赦拘,dart也擁有一些數(shù)字常用的函數(shù):
main() {
print(3.141592653.toStringAsFixed(3));//3.142 保留有效數(shù)字
print(6.6.floor());//6向下取整
print((-6.6).ceil());//-6 向上取整
print(9.9.ceil());//10 向上取整
print(666.6.round());//667 四舍五入
print((-666.6).abs());// 666.6 取絕對(duì)值
print(666.6.toInt());//666 轉(zhuǎn)化成int,這中toInt慌随、toDouble和Kotlin類似
print(999.isEven);//false 是否是偶數(shù)
print(999.isOdd);//true 是否是奇數(shù)
print(666.6.toString());//666.6 轉(zhuǎn)化成字符串
}
3、字符串類型(String)
在Dart中支持單引號(hào)、雙引號(hào)阁猜、三引號(hào)以及$字符串模板用法和Kotlin是一模一樣的丸逸。
main() {
Stringname='Hello Dart!';//單引號(hào)
Stringtitle="'Hello Dart!'";//雙引號(hào)
Stringdescription="""
Hello Dart! Hello Dart!
Hello Dart!
Hello Dart! Hello Dart!
"""
;//三引號(hào)
numvalue=2;
Stringresult="The result is $value";//單值引用
numwidth=200;
numheight=300;
Stringsquare="The square is ${width*height}";//表達(dá)式的值引用
}
和Kotlin一樣,dart中也有很多字符串操作的方法剃袍,比如字符串拆分黄刚、子串等
main() {
Stringurl="https://mrale.ph/dartvm/";
print(url.split("://")[0]);//字符串分割split方法,類似Java和Kotlin
print(url.substring(3,9));//字符串截取substring方法, 類似Java和Kotlin
print(url.codeUnitAt(0));//取當(dāng)前索引位置字符的UTF-16碼
print(url.startsWith("https"));//當(dāng)前字符串是否以指定字符開頭, 類似Java和Kotlin
print(url.endsWith("/"));//當(dāng)前字符串是否以指定字符結(jié)尾, 類似Java和Kotlin
print(url.toUpperCase());//大寫, 類似Java和Kotlin
print(url.toLowerCase());//小寫, 類似Java和Kotlin
print(url.indexOf("ph"));//獲取指定字符的索引位置, 類似Java和Kotlin
print(url.contains("http"));//字符串是否包含指定字符, 類似Java和Kotlin
print(url.trim());//去除字符串的首尾空格, 類似Java和Kotlin
print(url.length);//獲取字符串長(zhǎng)度
print(url.replaceFirst("t","A"));//替換第一次出現(xiàn)t字符位置的字符
print(url.replaceAll("m","M"));//全部替換, 類似Java和Kotlin
}
4民效、類型檢查(is和is!)和強(qiáng)制類型轉(zhuǎn)換(as)
和Kotlin一樣憔维,dart也是通過(guò)is關(guān)鍵字來(lái)對(duì)類型進(jìn)行檢查以及使用as關(guān)鍵字對(duì)類型進(jìn)行強(qiáng)制轉(zhuǎn)換,如果判斷不是某個(gè)類型dart中使用is!, 而在Kotlin中正好相反則用!is表示畏邢。
main() {
intnumber=100;
doubledistance=200.5;
numage=18;
print(numberisnum);//true
print(distanceis!int);//true
print(ageasint);//18
}
5业扒、Runes和Symbols類型
在Dart中的Runes和Symbols類型使用并不多,這里做個(gè)簡(jiǎn)單的介紹, Runes類型是UTF-32字節(jié)單元定義的Unicode字符串舒萎,Unicode可以使用數(shù)字表示字母凶赁、數(shù)字和符號(hào),然而在dart中String是一系列的UTF-16的字節(jié)單元逆甜,所以想要表示32位的Unicode的值,就需要用到Runes類型致板。我們一般使用\uxxxx這種形式來(lái)表示一個(gè)Unicode碼交煞,xxxx表示4個(gè)十六進(jìn)制值。當(dāng)十六進(jìn)制數(shù)據(jù)多余或者少于4位時(shí)斟或,將十六進(jìn)制數(shù)放入到花括號(hào)中素征,例如,微笑表情( )是\u{1f600}萝挤。而Symbols類型則用得很少御毅,一般用于Dart中的反射,但是注意在Flutter中禁止使用反射怜珍。
main() {
varclapping='\u{1f44f}';
print(clapping);
print(clapping.codeUnits);//返回十六位的字符單元數(shù)組
print(clapping.runes.toList());
Runes input=newRunes(
'\u2665? \u{1f605}? \u{1f60e}? \u{1f47b}? \u{1f596}? \u{1f44d}');
print(newString.fromCharCodes(input));
}
6端蛆、Object類型
在Dart中所有東西都是對(duì)象,都繼承于Object, 所以可以使用Object可以定義任何的變量酥泛,而且賦值后今豆,類型也可以更改。
main() {
Objectcolor='black';
color=0xff000000;//運(yùn)行正常柔袁,0xff000000類型是int, int也繼承于Object
}
7呆躲、dynamic類型
在Dart中還有一個(gè)和Object類型非常類似的類型那就是dynamic類型,下面講到的var聲明的變量未賦值的時(shí)候就是dynamic類型捶索, 它可以像Object一樣可以改變類型插掂。dynamic類型一般用于無(wú)法確定具體類型, 注意:建議不要濫用dynamic,一般盡量使用Object, 如果你對(duì)Flutter和Native原生通信PlatformChannel代碼熟悉的話,你會(huì)發(fā)現(xiàn)里面大量使用了dynamic, 因?yàn)榭赡躰ative數(shù)據(jù)類型無(wú)法對(duì)應(yīng)dart中的數(shù)據(jù)類型,此時(shí)dart接收一般就會(huì)使用dynamic.
Object和dynamic區(qū)別在于: Object會(huì)在編譯階段檢查類型辅甥,而dynamic不會(huì)在編譯階段檢查類型酝润。
main() {
dynamiccolor='black';
color=0xff000000;//運(yùn)行正常,0xff000000類型是int, int也繼承于Object
}
三肆氓、變量和常量
1袍祖、var關(guān)鍵字
在dart中可以使用var來(lái)替代具體類型的聲明,會(huì)自動(dòng)推導(dǎo)變量的類型谢揪,這是因?yàn)関ar并不是直接存儲(chǔ)值蕉陋,而是存儲(chǔ)值的對(duì)象引用,所以var可以聲明任何變量拨扶。這一點(diǎn)和Kotlin不一樣凳鬓,在Kotlin中聲明可變的變量都必須需要使用var關(guān)鍵字,而Kotlin的類型推導(dǎo)是默認(rèn)行為和var并沒有直接關(guān)系患民。注意: 在Flutter開發(fā)一般會(huì)經(jīng)常使用var聲明變量缩举,以便于可以自動(dòng)推導(dǎo)變量的類型。
main() {
intcolorValue=0xff000000;
varcolorKey='black';//var聲明變量 自動(dòng)根據(jù)賦值的類型匹颤,推導(dǎo)為String類型
// 使用var聲明集合變量
varcolorList=['red','yellow','blue','green'];
varcolorSet={'red','yellow','blue','green'};
varcolorMap={'white':0xffffffff,'black':0xff000000};
}
但是在使用var聲明變量的時(shí)候仅孩,需要注意的是:如果var聲明的變量開始不初始化,不僅值可以改變它的類型也是可以被修改的印蓖,但是一旦開始初始化賦值后辽慕,它的類型就確定了,后續(xù)不能被改變赦肃。
main() {
varcolor;// 僅有聲明未賦值的時(shí)候溅蛉,這里的color的類型是dynamic,所以它的類型是可以變的
color='red';
print(colorisString);//true
color=0xffff0000;
print(colorisint);//true
varcolorValue=0xffff0000;//聲明時(shí)并賦值,這里colorValue類型已經(jīng)推導(dǎo)出為int,并且確定了類型
colorValue='red';//錯(cuò)誤他宛,這里會(huì)拋出編譯異常船侧,String類型的值不能賦值給int類型
print(colorValueisint);//true
}
2、常量(final和const)
在dart中聲明常量可以使用const或final兩個(gè)關(guān)鍵字厅各,注意: 這兩者的區(qū)別在于如果常量是編譯期就能初始化的就用const(有點(diǎn)類似Kotlin中的const val) 如果常量是運(yùn)行時(shí)期初始化的就用final(有點(diǎn)類似Kotlin中的val)
main() {
constPI=3.141592653;//const定義常量
finalnowTime=DateTime.now();//final定義常量
}
四镜撩、集合(List、Set讯检、Map)
1琐鲁、集合List
在dart中的List和Kotlin還是很大的區(qū)別,換句話說(shuō)Dart整個(gè)集合類型系統(tǒng)的劃分都和Kotlin都不一樣人灼,比如Dart中集合就沒有嚴(yán)格區(qū)分成可變集合(Kotlin中MutableList)和不變集合(Kotlin中的List)围段,在使用方式上你會(huì)感覺它更像數(shù)組,但是它是可以隨意對(duì)元素增刪改成的投放。
List初始化方式
main() {
List colorList = ['red', 'yellow', 'blue', 'green'];//直接使用[]形式初始化
var colorList = ['red', 'yellow', 'blue', 'green'];
}
List常用的函數(shù)
main() {
List colorList = ['red', 'yellow', 'blue', 'green'];
colorList.add('white');//和Kotlin類似通過(guò)add添加一個(gè)新的元素
print(colorList[2]);//可以類似Kotlin一樣奈泪,直接使用數(shù)組下標(biāo)形式訪問(wèn)元素
print(colorList.length);//獲取集合的長(zhǎng)度,這個(gè)Kotlin不一樣,Kotlin中使用的是size
colorList.insert(1, 'black');//在集合指定index位置插入指定的元素
colorList.removeAt(2);//移除集合指定的index=2的元素涝桅,第3個(gè)元素
colorList.clear();//清除所有元素
print(colorList.sublist(1,3));//截取子集合
print(colorList.getRange(1, 3));//獲取集合中某個(gè)范圍元素
print(colorList.join('<--->'));//類似Kotlin中的joinToString方法拜姿,輸出: red<--->yellow<--->blue<--->green
print(colorList.isEmpty);
print(colorList.contains('green'));
}
List的遍歷方式
main() {
List colorList = ['red', 'yellow', 'blue', 'green'];//for-i遍歷
for(var i = 0; i < colorList.length; i++) {//可以使用var或int
print(colorList[i]);
}
//forEach遍歷
colorList.forEach((color) => print(color));//forEach的參數(shù)為Function. =>使用了箭頭函數(shù)
//for-in遍歷
for(var color in colorList) {
print(color);
}
//while+iterator迭代器遍歷,類似Java中的iteator
while(colorList.iterator.moveNext()) {
print(colorList.iterator.current);
}
}
2冯遂、集合Set
集合Set和列表List的區(qū)別在于集合中的元素是不能重復(fù)的蕊肥。所以添加重復(fù)的元素時(shí)會(huì)返回false,表示添加不成功.
Set初始化方式
main() {
Set colorSet= {'red', 'yellow', 'blue', 'green'};//直接使用{}形式初始化
var colorList = {'red', 'yellow', 'blue', 'green'};
}
集合中的交、并蛤肌、補(bǔ)集壁却,在Kotlin并沒有直接給到計(jì)算集合交、并裸准、補(bǔ)的API
main() {
varcolorSet1={'red','yellow','blue','green'};
varcolorSet2={'black','yellow','blue','green','white'};
print(colorSet1.intersection(colorSet2));//交集-->輸出: {'yellow', 'blue', 'green'}
print(colorSet1.union(colorSet2));//并集--->輸出: {'black', 'red', 'yellow', 'blue', 'green', 'white'}
print(colorSet1.difference(colorSet2));//補(bǔ)集--->輸出: {'red'}
}
Set的遍歷方式(和List一樣)
main() {
Set<String>colorSet={'red','yellow','blue','green'};
//for-i遍歷
for(vari=0; i<colorSet.length; i++) {
//可以使用var或int
print(colorSet[i]);
}
//forEach遍歷
colorSet.forEach((color)=>print(color));//forEach的參數(shù)為Function. =>使用了箭頭函數(shù)
//for-in遍歷
for(varcolorincolorSet) {
print(color);
}
//while+iterator迭代器遍歷展东,類似Java中的iteator
while(colorSet.iterator.moveNext()) {
print(colorSet.iterator.current);
}
}
3、集合Map
集合Map和Kotlin類似炒俱,key-value形式存儲(chǔ)盐肃,并且Map對(duì)象的中key是不能重復(fù)的
Map初始化方式
main() {
Map<String,int>colorMap={'white':0xffffffff,'black':0xff000000};//使用{key:value}形式初始化
varcolorMap=<String,int>{'white':0xffffffff,'black':0xff000000};
}
Map中常用的函數(shù)
main() {
Map<String,int>colorMap={'white':0xffffffff,'black':0xff000000};
print(colorMap.containsKey('green'));//false
print(colorMap.containsValue(0xff000000));//true
print(colorMap.keys.toList());//['white','black']
print(colorMap.values.toList());//[0xffffffff, 0xff000000]
colorMap['white']=0xfffff000;//修改指定key的元素
colorMap.remove('black');//移除指定key的元素
}
Map的遍歷方式
main() {
Map<String,int>colorMap={'white':0xffffffff,'black':0xff000000};
//for-each key-value
colorMap.forEach((key, value)=>print('color is $key, color value is $value'));
}
Map.fromIterables將List集合轉(zhuǎn)化成Map
main() {
List<String>colorKeys=['white','black'];
List<int>colorValues=[0xffffffff,0xff000000];
Map<String,int>colorMap=Map.fromIterables(colorKeys, colorValues);
}
4、集合常用的操作符
dart對(duì)于集合操作的也非常符合現(xiàn)代語(yǔ)言的特點(diǎn)权悟,含有豐富的集合操作符API砸王,可以讓你處理結(jié)構(gòu)化的數(shù)據(jù)更加簡(jiǎn)單。
main() {
List<String>colorList=['red','yellow','blue','green'];
//forEach箭頭函數(shù)遍歷
colorList.forEach((color)=>{print(color)});
colorList.forEach((color)=>print(color));//箭頭函數(shù)遍歷峦阁,如果箭頭函數(shù)內(nèi)部只有一個(gè)表達(dá)式可以省略大括號(hào)
//map函數(shù)的使用
print(colorList.map((color)=>'$color_font').join(","));
//every函數(shù)的使用处硬,判斷里面的元素是否都滿足條件,返回值為true/false
print(colorList.every((color)=>color=='red'));
//sort函數(shù)的使用
List<int>numbers=[0,3,1,2,7,12,2,4];
numbers.sort((num1, num2)=>num1-num2);//升序排序
numbers.sort((num1, num2)=>num2-num1);//降序排序
print(numbers);
//where函數(shù)使用拇派,相當(dāng)于Kotlin中的filter操作符,返回符合條件元素的集合
print(numbers.where((num)=>num>6));
//firstWhere函數(shù)的使用凿跳,相當(dāng)于Kotlin中的find操作符件豌,返回符合條件的第一個(gè)元素,如果沒找到返回null
print(numbers.firstWhere((num)=>num==5, orElse: ()=>-1));//注意: 如果沒有找到控嗜,執(zhí)行orElse代碼塊茧彤,可返回一個(gè)指定的默認(rèn)值
//singleWhere函數(shù)的使用,返回符合條件的第一個(gè)元素疆栏,如果沒找到返回null曾掂,但是前提是集合中只有一個(gè)符合條件的元素, 否則就會(huì)拋出異常
print(numbers.singleWhere((num)=>num==4, orElse: ()=>-1));//注意: 如果沒有找到,執(zhí)行orElse代碼塊壁顶,可返回一個(gè)指定的默認(rèn)值
//take(n)珠洗、skip(n)函數(shù)的使用,take(n)表示取當(dāng)前集合前n個(gè)元素, skip(n)表示跳過(guò)前n個(gè)元素若专,然后取剩余所有的元素
print(numbers.take(5).skip(2));
//List.from函數(shù)的使用许蓖,從給定集合中創(chuàng)建一個(gè)新的集合,相當(dāng)于clone一個(gè)集合
print(List.from(numbers));
//expand函數(shù)的使用, 將集合一個(gè)元素?cái)U(kuò)展成多個(gè)元素或者將多個(gè)元素組成二維數(shù)組展開成平鋪一個(gè)一位數(shù)組
varpair=[
[1,2],
[3,4]
];
print('flatten list: ${pair.expand((pair)=>pair)}');
varinputs=[1,2,3];
print('duplicated list: ${inputs.expand((number)=>[
number,
number,
number
])}');
}
五、流程控制
1、for循環(huán)
main() {
List<String>colorList=['red','yellow','blue','green'];
for(vari=0; i<colorList.length; i++) {//可以用var或int
print(colorList[i]);
}
}
2膊爪、while循環(huán)
main() {
List<String>colorList=['red','yellow','blue','green'];
varindex=0;
while(index<colorList.length) {
print(colorList[index++]);
}
}
3自阱、do-while循環(huán)
main() {
List<String>colorList=['red','yellow','blue','green'];
varindex=0;
do{
print(colorList[index++]);
}while(index<colorList.length);
}
4、break和continue
main() {
List<String>colorList=['red','yellow','blue','green'];
for(vari=0; i<colorList.length; i++) {//可以用var或int
if(colorList[i]=='yellow') {
continue;
}
if(colorList[i]=='blue') {
break;
}
print(colorList[i]);
}
}
5米酬、if-else
voidmain() {
varnumbers=[1,2,3,4,5,6,7,8,9,10,11];
for(vari=0; i<numbers.length; i++) {
if(numbers[i].isEven) {
print('偶數(shù): ${numbers[i]}');
}elseif(numbers[i].isOdd) {
print('奇數(shù): ${numbers[i]}');
}else{
print('非法數(shù)字');
}
}
}
6沛豌、三目運(yùn)算符(? : )
voidmain() {
varnumbers=[1,2,3,4,5,6,7,8,9,10,11];
for(vari=0; i<numbers.length; i++) {
numtargetNumber=numbers[i].isEven?numbers[i]*2:numbers[i]+4;
print(targetNumber);
}
}
7、switch-case語(yǔ)句
Color getColor(StringcolorName) {
Color currentColor=Colors.blue;
switch(colorName) {
case"read":
currentColor=Colors.red;
break;
case"blue":
currentColor=Colors.blue;
break;
case"yellow":
currentColor=Colors.yellow;
break;
}
returncurrentColor;
}
8赃额、Assert(斷言)
在dart中如果條件表達(dá)式結(jié)果不滿足條件加派,則可以使用assert語(yǔ)句中斷代碼的執(zhí)行。特別是在Flutter源碼中隨處可見都是assert斷言的使用爬早。注意:斷言只在檢查模式下運(yùn)行有效哼丈,如果在生產(chǎn)模式運(yùn)行,則斷言不會(huì)執(zhí)行筛严。
assert(text!=null);//text為null,就會(huì)中斷后續(xù)代碼執(zhí)行
assert(urlString.startsWith('https'));
六醉旦、運(yùn)算符
1、算術(shù)運(yùn)算符
| 名稱 | 運(yùn)算符 | 例子 |
|:---:|:---:|:-------------------------:|
| 加 | + | var result = 1 + 1; |
| 減 | - | var result = 5 - 1; |
| 乘 | * | var result = 3 * 5; |
| 除 | / | var result = 3 / 5;?//0.6?|
| 整除 | ~/ | var result = 3 ~/ 5; //0 |
| 取余 | % | var result = 5 % 3; //2 |
2桨啃、條件運(yùn)算符
| 名稱 | 運(yùn)算符 | 例子 |
|:----:|:---:|:------:|
| 大于 | > | 2 > 1 |
| 小于 | < | 1 < 2 |
| 等于 | == | 1 == 1 |
| 不等于 | != | 3 != 4 |
| 大于等于 | >= | 5 >= 4 |
| 小于等于 | <= | 4 <= 5 |
3车胡、邏輯運(yùn)算符
| 名稱 | 運(yùn)算符 | 例子 |
|:---:|:----:|:----------------:|
| 或 | \|\| | 2 > 1 \|\| 3 < 1 |
| 與 | && | 2 > 1 && 3 < 1 |
| 非 | !| !(2 > 1) |
4照瘾、位運(yùn)算符
| 名稱 | 運(yùn)算符 |
|:---:|:---:|
| 位與 | & |
| 位或 | \| |
| 位非 | ~ |
| 異或 | ^ |
| 左移 | << |
| 右移 | >> |
5匈棘、三目運(yùn)算符
condition ? expr1 : expr2
varisOpened=(value==1)?true:false;
6、空安全運(yùn)算符
| 操作符 | 解釋 |
|:-----------------------:|:---------------------------------------:|
| result = expr1 ?? expr2 | 若expr1為null, 返回expr2的值析命,否則返回expr1的值 |
| expr1 ??= expr2 | 若expr1為null, 則把expr2的值賦值給expr1 |
| result = expr1?.value | 若expr1為null, 就返回null,否則就返回expr1.value的值 |
1主卫、result = expr1 ?? expr2
如果發(fā)現(xiàn)expr1為null,就返回expr2的值,否則就返回expr1的值, 這個(gè)類似于Kotlin中的result = expr1 ?: expr2
main() {
varchoice=question.choice??'A';
//等價(jià)于
varchoice2;
if(question.choice==null) {
choice2='A';
}else{
choice2=question.choice;
}
}
2鹃愤、expr1 ??= expr2等價(jià)于expr1 = expr1 ?? expr2(轉(zhuǎn)化成第一種)
main() {
varchoice??='A';
//等價(jià)于
if(choice==null) {
choice='A';
}
}
3簇搅、result = expr1?.value
如果expr1不為null就返回expr1.value,否則就會(huì)返回null, 類似Kotlin中的 ?. 如果expr1不為null,就執(zhí)行后者
varchoice=question?.choice;//等價(jià)于
if(question==null){
returnnull;
}else{
returnquestion.choice;
}
question?.commit();//等價(jià)于
if(question==null){
return;//不執(zhí)行commit()
}else{
question.commit();//執(zhí)行commit方法
}
7软吐、級(jí)聯(lián)操作符(..)
級(jí)聯(lián)操作符是.., 可以讓你對(duì)一個(gè)對(duì)象中字段進(jìn)行鏈?zhǔn)秸{(diào)用操作瘩将,類似Kotlin中的apply或run標(biāo)準(zhǔn)庫(kù)函數(shù)的使用。
question
..id='10001'
..stem='第一題: xxxxxx'
..choices=<String>['A','B','C','D']
..hint='聽音頻做題';
Kotlin中的run函數(shù)實(shí)現(xiàn)對(duì)比
question.run {
id ='10001'
stem ='第一題: xxxxxx'
choices = ['A','B','C','D']
hint ='聽音頻做題'
}
8凹耙、運(yùn)算符重載
在dart支持運(yùn)算符自定義重載,使用operator關(guān)鍵字定義重載函數(shù)
classVip{
finalintlevel;
finalintscore;
constVip(this.level,this.score);
booloperator>(Vip other)=>
level>other.level||(level==other.level&&score>other.score);
booloperator<(Vip other)=>
level<other.level||(level==other.level&&score<other.score);
booloperator==(Vip other)=>
level==other.level&&
score==other.level;//注意: 這段代碼可能在高版本的Dart中會(huì)報(bào)錯(cuò)姿现,在低版本是OK的
//上述代碼,在高版本Dart中肖抱,Object中已經(jīng)重載了==,所以需要加上covariant關(guān)鍵字重寫這個(gè)重載函數(shù)备典。
@override
booloperator==(covariant Vip other)=>
(level==other.level&&score==other.score);
@override
intgethashCode=>super.hashCode;//伴隨著你還需要重寫hashCode,至于什么原因大家應(yīng)該都知道
}
main() {
varuserVip1=Vip(4,3500);
varuserVip2=Vip(4,1200);
if(userVip1>userVip2) {
print('userVip1 is super vip');
}elseif(userVip1<userVip2) {
print('userVip2 is super vip');
}
}
七意述、異常
dart中的異常捕獲方法和Java,Kotlin類似熊经,使用的也是try-catch-finally; 對(duì)特定異常的捕獲使用on關(guān)鍵字. dart中的常見異常有:NoSuchMethodError(當(dāng)在一個(gè)對(duì)象上調(diào)用一個(gè)該對(duì)象沒有 實(shí)現(xiàn)的函數(shù)會(huì)拋出該錯(cuò)誤)泽艘、ArgumentError(調(diào)用函數(shù)的參數(shù)不合法會(huì)拋出這個(gè)錯(cuò)誤)
main() {
intnum=18;
intresult=0;
try{
result=num~/0;
}catch(e) {//捕獲到IntegerDivisionByZeroException
print(e.toString());
}finally{
print('$result');
}
}
//使用on關(guān)鍵字捕獲特定的異常
main() {
intnum=18;
intresult=0;
try{
result=num~/0;
} on IntegerDivisionByZeroExceptioncatch(e) {//捕獲特定異常
print(e.toString());
}finally{
print('$result');
}
}
八、函數(shù)
在dart中函數(shù)的地位一點(diǎn)都不亞于對(duì)象镐依,支持閉包和高階函數(shù)匹涮,而且dart中的函數(shù)也會(huì)比Java要靈活的多,而且Kotlin中的一些函數(shù)特性槐壳,它也支持甚至比Kotlin支持的更全面然低。比如支持默認(rèn)值參數(shù)、可選參數(shù)务唐、命名參數(shù)等.
1雳攘、函數(shù)的基本用法
main() {
print('sum is ${sum(2,5)}');
}
numsum(numa,numb) {
returna+b;
}
2、函數(shù)參數(shù)列表傳參規(guī)則
//num a, num b, num c, num d 最普通的傳參: 調(diào)用時(shí)枫笛,參數(shù)個(gè)數(shù)和參數(shù)順序必須固定
add1(numa,numb,numc,numd) {
print(a+b+c+d);
}
//[num a, num b, num c, num d]傳參: 調(diào)用時(shí)吨灭,參數(shù)個(gè)數(shù)不固定,但是參數(shù)順序需要一一對(duì)應(yīng), 不支持命名參數(shù)
add2([numa,numb,numc,numd]) {
print(a+b+c+d);
}
//{num a, num b, num c, num d}傳參: 調(diào)用時(shí)刑巧,參數(shù)個(gè)數(shù)不固定喧兄,參數(shù)順序也可以不固定,支持命名參數(shù),也叫可選參數(shù)啊楚,是dart中的一大特性吠冤,這就是為啥Flutter代碼那么多可選屬性,大量使用可選參數(shù)
add3({numa,numb,numc,numd}) {
print(a+b+c+d);
}
//num a, num b, {num c, num d}傳參: 調(diào)用時(shí)恭理,a,b參數(shù)個(gè)數(shù)固定順序固定拯辙,c,d參數(shù)個(gè)數(shù)和順序也可以不固定
add4(numa,numb, {numc,numd}) {
print(a+b+c+d);
}
main() {
add1(100,100,100,100);//最普通的傳參: 調(diào)用時(shí),參數(shù)個(gè)數(shù)和參數(shù)順序必須固定
add2(100,100);//調(diào)用時(shí)颜价,參數(shù)個(gè)數(shù)不固定涯保,但是參數(shù)順序需要一一對(duì)應(yīng), 不支持命名參數(shù)(也就意味著順序不變)
add3(
b:200,
a:200,
c:100,
d:100);//調(diào)用時(shí),參數(shù)個(gè)數(shù)不固定周伦,參數(shù)順序也可以不固定遭赂,支持命名參數(shù)(也就意味著順序可變)
add4(100,100, d:100, c:100);//調(diào)用時(shí),a,b參數(shù)個(gè)數(shù)固定順序篤定横辆,c,d參數(shù)個(gè)數(shù)和順序也可以不固定
}
3、函數(shù)默認(rèn)參數(shù)和可選參數(shù)(以及與Kotlin對(duì)比)
dart中函數(shù)的默認(rèn)值參數(shù)和可選參數(shù)和Kotlin中默認(rèn)值參數(shù)和命名參數(shù)一致茄猫,只是寫法上不同而已
add3({numa,numb,numc,numd=100}) {//d就是默認(rèn)值參數(shù)狈蚤,給的默認(rèn)值是100
print(a+b+c+d);
}
main() {
add3(b:200, a:100, c:800);
}
與Kotlin對(duì)比
funadd3(a: Int, b: Int, c: Int, d: Int =100) {
println(a + b + c + d)
}
funmain(args: Array) {
add3(b =200, a =100, c =800)
}
4、函數(shù)類型與高階函數(shù)
在dart函數(shù)也是一種類型Function,可以作為函數(shù)參數(shù)傳遞划纽,也可以作為返回值脆侮。類似Kotlin中的FunctionN系列函數(shù)
main() {
Function square=(a) {
returna*a;
};
Function square2=(a) {
returna*a*a;
};
add(3,4, square, square2)
}
numadd(numa,numb, [Function op, Function op2]) {
//函數(shù)作為參數(shù)傳遞
returnop(a)+op2(b);
}
5、函數(shù)的簡(jiǎn)化以及箭頭函數(shù)
在dart中的如果在函數(shù)體內(nèi)只有一個(gè)表達(dá)式勇劣,那么就可以使用箭頭函數(shù)來(lái)簡(jiǎn)化代碼靖避,這點(diǎn)也和Kotlin類似潭枣,只不過(guò)在Kotlin中人家叫l(wèi)ambda表達(dá)式,只是寫法上不一樣而已幻捏。
add4(numa,numb, {numc,numd}) {
print(a+b+c+d);
}
add5(numa,numb, {numc,numd})=>print(a+b+c+d);
九盆犁、面向?qū)ο?/p>
在dart中一切皆是對(duì)象,所以面向?qū)ο笤贒art中依然舉足輕重篡九,下面就先通過(guò)一個(gè)簡(jiǎn)單的例子認(rèn)識(shí)下dart的面向?qū)ο笮乘辏罄m(xù)會(huì)繼續(xù)深入。
1榛臼、類的基本定義和使用
abstractclassPerson{
Stringname;
intage;
doubleheight;
Person(this.name,this.age,this.height);//注意伊佃,這里寫法可能大家沒見過(guò), 這點(diǎn)和Java是不一樣沛善,這里實(shí)際上是一個(gè)dart的語(yǔ)法糖航揉。但是這里不如Kotlin,Kotlin是直接把this.name傳值的過(guò)程都省了金刁。
//與上述的等價(jià)代碼,當(dāng)然這也是Java中必須要寫的代碼
Person(Stringname,intage,doubleheight) {
this.name=name;
this.age=age;
this.height=height;
}
//然而Kotlin很徹底只需要聲明屬性就行,下面是Kotlin實(shí)現(xiàn)代碼
abstractclassPerson(val name:String, val age: Int, val height: Double)
}
classStudentextendsPerson {//和Java一樣同時(shí)使用extends關(guān)鍵字表示繼承
Student(Stringname,intage,doubleheight,doublegrade):super(name, age, height);//在 Dart里:類名(變量帅涂,變量,...) 是構(gòu)造函數(shù)的寫法, :super()表示該構(gòu)造調(diào)用父類,這里構(gòu)造時(shí)傳入三個(gè)參數(shù)
}
2胀葱、類中屬性的getter和setter訪問(wèn)器(類似Kotlin)
abstractclassPerson{
String_name;////相當(dāng)于kotlin中的var 修飾的變量有setter漠秋、getter訪問(wèn)器,在dart中沒有訪問(wèn)權(quán)限, 默認(rèn)_下劃線開頭變量表示私有權(quán)限抵屿,外部文件無(wú)法訪問(wèn)
finalint_age;//相當(dāng)于kotlin中的val 修飾的變量只有g(shù)etter訪問(wèn)器
Person(this._name,this._age);//這是上述簡(jiǎn)寫形式
//使用set關(guān)鍵字 計(jì)算屬性 自定義setter訪問(wèn)器
setname(Stringname)=>_name=name;
//使用get關(guān)鍵字 計(jì)算屬性 自定義getter訪問(wèn)器
boolgetisStudent=>_age>18;
}
喜歡的點(diǎn)個(gè)贊或者關(guān)注哦庆锦,謝謝