Flutter開發之Dart語法基礎

dart-logo

  • 原文博客地址: Flutter開發之Dart語法基礎
  • Dart是谷歌在 2011 年推出的編程語言,是一種結構化Web編程語言,容許用戶經過Chromium中所整合的虛擬機(Dart VM)直接運行Dart 語言編寫的程序,免去了單獨編譯的步驟
  • 之後這些程序將從Dart VM更快的性能與較低的啓動延遲中受益
  • Dart從設計之初就爲配合現代web總體運做而考慮,開發團隊也同時在持續改進DartJavaScript轉換的快速編譯器
  • Dart VM以及現代JavaScript引擎(V8 等)都是Dart語言的首選目標平臺
  • Dart語言和Swift語言有不少的類似之處

重要概念

在學習Dart語言以前, 先了解一些Dart相關的一些概念:web

  • O-Objective中有一切皆對象的說法, 這句話在Dart中一樣適用
    • 全部可以使用變量引用的都是對象, 每一個對象都是一個類的實例
    • Dart中 甚至連 數字、方法和null都是對象
    • 全部的對象都繼承於Object
  • Dart動態類型語言, 儘可能給變量定義一個類型,會更安全,沒有顯示定義類型的變量在debug模式下會類型會是dynamic(動態的)
  • Dart會在運行以前解析你的全部代碼,指定數據類型和編譯時的常量,能夠提升運行速度
  • Dart中的類和接口是統一的,類即接口,你能夠繼承一個類,也能夠實現一個類(接口),天然也包含了良好的面向對象和併發編程的支持
  • Dart函數
    • 支持頂級函數 (例如main())
    • 支持在類中定義函數, 如靜態函數和實例函數
    • 還能夠在方法中定義方法(嵌套方法或者局部方法)
  • 相似的,Dart支持頂級變量,以及依賴於類或對象(靜態變量和實例變量)變量。實例變量有時被稱爲域或屬性
  • Dart不具有關鍵字publicprotectedprivate。若是一個標識符如下劃線(_)開始,那麼它和它的庫都是私有的
  • 標識符能夠字母或(_)開始,或者是字符加數字的組合開頭

以上只是大概說明了一些Dart中的重要概念, 具體的語法使用, 請看下文編程

基本語法

註釋

Dart的註釋分爲3種:單行註釋、多行註釋、文檔註釋安全

  • 單行註釋以//開頭
  • 多行註釋以/*開頭,以*/結尾
  • 文檔註釋以///或者/**開頭

分號;

  • 分號用於分隔Dart語句
  • 一般咱們在每條可執行的語句結尾添加分號
  • 使用分號的另外一用處是在一行中編寫多條語句
  • Dart中,用分號來結束語句是必須的, 不加分則會報錯

其餘語法

  • 按照Dart的編程規範,使用2個空格來縮進
  • 輸出語句使用print(Object)

變量和常量

變量

使用varObjectdynamic關鍵字聲明變量bash

var name = 'name';
dynamic name1 = 'name1';
String name2 = 'name2';

// 變量的賦值
name = 'a';
name1 = 'a1';
name2 = 'a2';
複製代碼

未初始化的變量的初始值爲null, 即便是數字也是如此,由於在Dart中數字也是一個對象微信

var name;
dynamic name1;
String name2;
複製代碼

可選類型併發

在聲明變量的時候,你能夠選擇加上具體的類型:less

String name2 = 'name2';
複製代碼
  • 這種方式能夠更加清晰的表達你想要定義的變量的類型, 編譯器也能夠根據該類型爲你提供代碼補全、提早發現 bug 等功能
  • 注意: 對於局部變量,這裏遵照 代碼風格推薦 部分的建議,使用var而不是具體的類型來定義局部變量

常量

  • 常量使用final或者const
  • 一個final變量只能賦值一次
  • 一個const變量是編譯時常量
  • 實例變量能夠爲final可是不能是const

final

final修飾的變量(即常量2)編程語言

final age = 10;
  final int age1 = 20;

  // final修飾的變量不能從新賦值, 會報錯
  age = 20;
  age1 = 30;
複製代碼

const

  • const變量爲編譯時常量
  • 若是在類中使用const定義常量,請定義爲static const
  • 使用const定義的常量, 能夠直接給定初始值,也可使用其餘const變量的值來初始化其值
// const
  const m1 = 12;
  const double m2 = 23;
  const m3 = m1 + m2;

  // final修飾的變量不能從新賦值, 會報錯
  m1 = 10;
  m2 = 1.02;
複製代碼

操做符

算術操做符

Dart支持經常使用的算術操做符ide

操做符 解釋
+ 加號
減號
-expr 負號
* 乘號
/ 除號(值爲double類型)
~/ 除號,可是返回值爲整數
% 取模

示例:函數

assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5);   // 結果是double類型
assert(5 ~/ 2 == 2);    // 結果是integer類型 
assert(5 % 2 == 1);     // 餘數
複製代碼

自加自減

Dart還支持自加自減操做

  • ++var: 先自加在使用
  • var++: 先使用在自加
  • --var: 先自減在使用
  • var--: 先使用在自減

示例

var a = 0, b = 0;
  
  b = a++;
  print('a = $a, b = $b'); //a = 1, b = 0
  b = ++a;
  print('a = $a, b = $b'); //a = 2, b = 2


  b = a--;
  print('a = $a, b = $b'); //a = 1, b = 2
  b = --a;
  print('a = $a, b = $b'); //a = 0, b = 0
複製代碼

關係操做符

運算符 含義
== 等於
!= 不等於
> 大於
< 小於
>= 大於等於
<= 小於等於
  • 要測試兩個對象表明的是否爲一樣的內容,使用 == 操做符
  • 在某些狀況下,你須要知道兩個對象是不是同一個對象, 使用identical()方法
external bool identical(Object a, Object b);
複製代碼

類型斷定操做符

類型斷定操做符是在運行時斷定對象類型的操做符

操做符 解釋
as 類型轉換
is 若是對象是指定的類型返回 True
is! 若是對象是指定的類型返回 False
  • 只有當obj實現了 T 的接口, obj is T 纔是true。例如obj is Object老是true
  • 使用as操做符把對象轉換爲特定的類型
  • 能夠把as它當作用is斷定類型而後調用 所斷定對象的函數的縮寫形式
if (emp is Person) { // Type check
  emp.firstName = 'Bob';
}

// 上面代碼可簡化爲
(emp as Person).firstName = 'Bob';
複製代碼

注意: 若是empnull或者不是Person類型,則第一個示例使用is則不會執行條件裏面的代碼,而第二個狀況使用as則會拋出一個異常; 因此在不缺定emp是否爲空的狀況下, 安全起見, 建議使用第一種方式

賦值操做符

= –= /= %= >>= ^=
+= *= ~/= <<= &=

示例:

// 給 a 變量賦值
a = value;  

// 複合賦值操做符
a += b;  // 等價於a = a + b;

// 若是 b 是 null,則賦值給 b;
// 若是不是 null,則 b 的值保持不變
b ??= value; 
     
// 以下所示: 
  var s;
  print(s);  // null
  print(s ?? 'str');  // str
  s ??= 'string';
  print(s);  // string
複製代碼

邏輯操做符

可使用邏輯操做符來 操做布爾值:

  • !expr: 對錶達式結果取反(true 變爲 false ,false 變爲 true)
  • ||: 邏輯 OR
  • &&: 邏輯 AND

條件表達式

condition ? expr1 : expr2
// 若是 condition 是 true,執行 expr1 (並返回執行的結果); 不然執行 expr2 並返回其結果

expr1 ?? expr2
// 若是 expr1 是 non-null,返回其值; 不然執行 expr2 並返回其結果
複製代碼

示例:

String toString() => msg ?? super.toString();

// 上面的代碼等價於
String toString() => msg == null ? super.toString() : msg;

// 等價於
String toString() {
  if (msg == null) {
    return super.toString();
  } else {
    return msg;
  }
}
複製代碼

級聯操做符

級聯操做符 (..) 能夠在同一個對象上 連續調用多個函數以及訪問成員變量。 使用級聯操做符能夠避免建立 臨時變量, 而且寫出來的代碼看起來 更加流暢

querySelector('#button') // Get an object.
  ..text = 'Confirm'   // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));
複製代碼

第一個方法querySelector()返回了一個selector對象。 後面的級聯操做符都是調用這個對象的成員, 並忽略每一個操做 所返回的值

// 上面代碼等價於
var button = querySelector('#button');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
複製代碼

級聯調用也能夠嵌套:

final addressBook = (new AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (new PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();
複製代碼

注意:嚴格來講,兩個點的級聯語法不是一個操做符, 只是一個Dart特殊語法。

流程控制語句

Dart中可使用下面的語句來控制Dart代碼的流程:

  • if-else
  • forfor-in
  • whiledo-while
  • switch
  • assert
  • breakcontinue
  • try-catchthrow

if-else

Dart支持if語句以及可選的else

if (a == 0) {
    print('a = 0');
  } else if (a == 1) {
    print('a = 1');
  } else {
    print('a = 2');
  }
複製代碼

注意點: 上述代碼中的條件控制語句的結果必須是布爾值

for

可使用標準的for循環, ListSet等實現了Iterable接口的類還支持for-in形式的遍歷:

var arr = [0, 1, 2];

  // for循環
  for (var i = 0; i < arr.length; i++) {
    print(arr[i]);
  }
  
  // for-in循環
  for (var x in arr) {
    print(x);
  }
複製代碼

Whiledo-while

// while 循環在執行循環以前先判斷條件是否知足:
  while (c == 0) {
    print('c = $c');
  }

  // 而do-while循環是先執行循環代碼再判斷條件:
  do {
    print('c = $c');
  } while (c == 0);
複製代碼

Breakcontinue

使用break來終止循環:

while (true) {
  if (shutDownRequested()) break;
  processIncomingRequests();
}
複製代碼

使用continue來開始下一次循環

for (int i = 0; i < candidates.length; i++) {
  var candidate = candidates[i];
  if (candidate.yearsExperience < 5) {
    continue;
  }
  candidate.interview();
}
複製代碼

Switch

  • Dart中的Switch語句使用 == 比較 integerstring、或者編譯時常量
  • 比較的對象必須都是同一個類的實例, 比較適合枚舉值
  • 每一個非空的case語句都必須有一個break語句
  • 另外還能夠經過continuethrow或者return來結束非空case語句
  • 當沒有case語句匹配的時候,可使用default語句來匹配這種默認狀況
  • 每一個case語句能夠有局部變量,局部變量只有在這個語句內可見
var command = 'OPEN';
  switch (command) {
    case 'CLOSED':
      print('CLOSED');
      break;
    case 'APPROVED':
      print('APPROVED');
      // break;
      // 這裏非空的case, 沒有break會報錯
    case 'DENIED':
      // 這裏空的case, 能夠不要break
    case 'OPEN':
      print('OPEN');
      continue nowClosed;
  //若是你須要實現這種繼續到下一個 case 語句中繼續執行,則能夠 使用 continue 語句跳轉到對應的標籤(label)處繼續執行:
  nowClosed:
    case 'PENDING':
      print('PENDING');
      break;
    default:
      print('default');
  }
複製代碼

Assert

  • 斷言: 若是條件表達式結果不知足須要,則可使用assert 語句中斷代碼的執行
  • assert方法的參數能夠爲任何返回布爾值的表達式或者方法。
  • 若是返回的值爲true,斷言執行經過,執行結束
  • 若是返回值爲false,斷言執行失敗,會拋出一個異常
  • 可在開發過程當中, 監測代碼是否有問題時使用
// Make sure the variable has a non-null value
assert(text != null);

// Make sure the value is less than 100
assert(number < 100);

// Make sure this is an https URL
assert(urlString.startsWith('https'));
複製代碼

注意:斷言只在開發模式下運行有效,若是在生產模式 運行,則斷言不會執行

這篇文章的簡單介紹就到這裏了, 下一篇將會記錄Dart的基本數據類型

參考文獻


歡迎您掃一掃下面的微信公衆號,訂閱個人博客!

微信公衆號
相關文章
相關標籤/搜索