Flutter之旅:Dart的基礎語法

張風捷特烈發表於2019-07-04

1.Dart中常見資料型別一覽:

總的來看Dart的常見的資料型別有下面8種:

Flutter之旅:Dart的基礎語法

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');//支援字串中使用變數
複製程式碼

Flutter之旅:Dart的基礎語法


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;
複製程式碼

Flutter之旅:Dart的基礎語法


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.運算子

常見運算子一覽

Flutter之旅:Dart的基礎語法

3.1:算術運算子

四則運算

Flutter之旅:Dart的基礎語法

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  商
複製程式碼

自加自減

Flutter之旅:Dart的基礎語法

---->[情況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:關係運算子

Flutter之旅:Dart的基礎語法

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:位運算子

Flutter之旅:Dart的基礎語法

拿兩個數來說明一下位運算: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:邏輯運算子

Flutter之旅:Dart的基礎語法

下面的程式碼表示:年齡大於22或者身高大於160的女性可以進入。

bool enter(int age, int height, bool isMan) {
  return (age > 18 || height > 140) && !isMan;
}
複製程式碼
3.5:賦值運算子

Flutter之旅:Dart的基礎語法

上圖中的下面一行都是運算子和等號的組合,其中

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中,一個函式的基本組成如下:

Flutter之旅: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的物件導向

相關文章