1.Dart中常見資料型別一覽:
總的來看Dart的常見的資料型別有下面8種:
1.1.數字型別
num、int和double都是Dart中的類,也就是說它是物件級別的,所以他們的預設值為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 ?,對應的Unicode為
\u{1f47f}
,看一下他的UTF-16碼
var evil = '\u{1f47f}';
print(evil);//?
print(evil.codeUnits);//[55357, 56447]
複製程式碼
通過
xxx.runes
方法,可以獲得一個Runes物件,可以看出一個emoji是和一個Runes元素對應的,而不像UTF-16需要兩個碼聯合起來才可以表示。這就有一個好處:我們可以將emoji當做可迭代的元素進行處理。
var evil = '\u{1f47f}\u{1f47a}\u{1f47b}';
print(evil);//???
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));//⚕??♓??⚔??
print(String.fromCharCodes(input.map((e){
return e-5;
})));//⚐??♎??⚏??
複製程式碼
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);//優秀
複製程式碼
5.7:assert
assert(條件)如果條件不滿足,會中斷程式的執行,否則繼續執行流程。
assert(1>2); //程式中斷
複製程式碼
本文到此接近尾聲了,另外本人有一個Flutter微信交流群,歡迎小夥伴加入,共同探討Flutter的問題,本人微訊號:
zdl1994328
,期待與你的交流與切磋。如果想快速嚐鮮Flutter,《Flutter七日》會是你的必備佳品。
Dart 的基礎語法就這樣,下面將進入Dart的物件導向