Dart語法:基礎(chǔ)

目錄

  1. 前言
  2. 代碼注釋
  3. 變量和常量
  4. 數(shù)據(jù)類型
  5. 操作符
  6. 控制流
  7. 異常

前言

  1. 本篇開始講解Dart語法,期間會通過對比Java、kotlin、Python、Groovy來區(qū)分語言直接的不同。

  2. 行尾分號

    Dart中每行代碼以分號為標示,代表本行結(jié)束。和Java一樣,kotlin、groovy、Python中不需要行尾分號。

  3. 生產(chǎn)環(huán)境和開發(fā)環(huán)境

    說下個人理解生產(chǎn)環(huán)境就是正式上線后的環(huán)境,開發(fā)環(huán)境就是開發(fā)過程中的環(huán)境。有點類似Android中的Release模式和Debug模式。

代碼注釋

  1. 行注釋

    和java一樣,雙引號//來注釋單行代碼

  2. 多行注釋

  3. Dart中使用/* … */用來注釋一段代碼(可以是一行,也可以是多行)。

  4. 文檔注釋

    • 用來對一個類或者方法進行說明的注釋內(nèi)容。位于類之前或者方法之前。

    • 可以使用 /// 開始, 也可以使用 /** 開始 并以 */ 結(jié)束

    • 在文檔注釋中可以使用中括號[]來引用 classes、 methods、 fields、 top-level variables、 functions、 和 parameters等內(nèi)容。

變量和常量

  1. 變量的定義

    • var 自動類型推斷

      如這種樣式:var name = 'Bob'; 使用var來聲明一個變量,然后通過初始化賦值來自動進行類型推斷。

    • 顯示聲明

      如這種:String name = 'Bob';和Java一樣直接聲明變量的類型。

  2. 變量的默認值

    所有變量的默認值都是null。Dart中一切都是對象,即使是數(shù)字類型,也是一個對象。

    示例代碼:

    int lineCount;
    assert(lineCount == null);  // 生產(chǎn)環(huán)境中asset會忽略,開發(fā)環(huán)境如果條件非true會拋異常
    
  3. 常量

    在使用過程中不會被修改的變量,我們稱之為常量。Dart中的常量分為兩種:

    • final:只能被賦值一次的變量。
    • const:在編譯時就固定的常量。如果希望常量是類級別的,需要使用需要標記為 static const來修飾,類似java中的static。

    定義和初始化方法:

    final name = 'Bob';  // 自動類型推斷,此時不需要var來修飾;
    final String nickname = 'Bobby';  // 顯示聲明,直接執(zhí)行數(shù)據(jù)類型;
    const bar = 1000000;
    const double atm = 1.01325 * bar;
    

數(shù)據(jù)類型

  1. Dart中支持的數(shù)據(jù)類型,也叫內(nèi)建類型。包含:Number、String、Boolean、List、Map、Set、Rune、Symbol。

  2. Number

    Number是數(shù)字類型,又細分為int和double:

    • int:整數(shù)類型。取值范圍取決于平臺,DartVM上是-2^63 到 2^63 - 1之間。如果被編譯為JS,那么取值范圍就是-2^53 到 2^53 - 1。
    • double:雙精度浮點類型,也就是帶小數(shù)點的數(shù)據(jù)類型。

    Number類型的初始化

    var x = 1;  // 默認十進制
    var hex = 0xDEADBEEF;  // 十六進制
    var y = 1.1;  // 自動推斷為double
    var exponents = 1.42e5;  // 科學(xué)計數(shù)法
    double z = 1; // 相當(dāng)于 double z = 1.0  從Dart2.1開始直接,之前的版本會報錯
    

    Number和字符串轉(zhuǎn)換

    字符串轉(zhuǎn)Number,直接使用int/double中的parse函數(shù),直接傳入字符串即可

    var one = int.parse('1');  // String -> int , 輸出為1
    var onePointOne = double.parse('1.1');  // String -> double
    

    Number轉(zhuǎn)字符串,直接使用toString()函數(shù)即可

    String oneAsString = 1.toString();  // int轉(zhuǎn)字符串
    String piAsString = 3.14159.toStringAsFixed(2);  // 轉(zhuǎn)為字符串并只保留后兩位,輸出為3.14
    
  3. String字符串

    創(chuàng)建字符串

    可以使用單引號、雙引號、三引號來定義一個字符串

    • 單引號:使用單引號來定義一個字符串。單引號中如果需要嵌套其它引號,需要在引號前加\來進行轉(zhuǎn)義。

    • 雙引號:和單引號類似,但雙引號中可以直接嵌套單引號,不需要轉(zhuǎn)義。

    • 三引號:使用三個單引號或者三個雙引號來定義一段字符串。這種字符串可以包含多行。

      var s1 = '''
      You can create
      multi-line strings like this one.
      ''';
      
      var s2 = """This is also a
      multi-line string.""";
      

    字符串中引用變量

    字符串可以通過 ${expression} 的方式內(nèi)嵌表達式。 如果表達式是一個標識符,則 {} 可以省略。

    var s = 'string interpolation';
    var result = '${s.toUpperCase()} is very handy!';
    

    原始字符串

    當(dāng)我們希望整個字符串中任何轉(zhuǎn)移字符都不生效,而是要保留純文本含義,那么可以在字符前加一個r標志來表明這是一個原始字符串。類似于Python。

    示例代碼:

    var s = r"在Dart中使用 \n 來標示換行";  // 這里的\n并沒有直接被轉(zhuǎn)義為換行符
    

    字符串相等比較

    使用==來比較兩個字符串是否相等。

    字符串拼接

    將多個字符串拼接為一個字符串,直接使用+來連接兩個字符串即可。

  4. Boolean布爾

    有兩個值truefalse。這兩個值也是一個對象。

    定義一個布爾變量使用bool

  5. List數(shù)組

    定義方式

    使用中括號

    var list = [1, 2, 3];
    

    注意:只能插入同類型的元素,如果類型不一致會報錯。

    讀取元素

    使用下標來獲取某個元素。下標從0開始。

  6. Set

    一個無序不重復(fù)的序列。在Set中每個元素都是唯一的,不會出現(xiàn)重復(fù)的元素,有的話會自動刪除。類似Python中的元祖。

    定義Set

    使用大括號來定義

    var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
    var names = <String>{};;  // 定義一個空字符串Set
    var names = {};  // 定義一個空Set
    

    添加元素

    var elements = <String>{};
    elements.add('fluorine');
    elements.addAll(halogens);
    
  7. Map字典

    Dart中用來存放鍵值對的一種數(shù)據(jù)類型,我們稱之為Map,也就是字典。在map中一個key只能出現(xiàn)一次。當(dāng)我們從map中取元素時,如果key不存在,那么不會拋異常,但是會返回null。key可以是字符串,也可以是純數(shù)字。

    Map對象的定義和初始化

    Map和Set一樣,都是使用大括號來進行初始化賦值。區(qū)別就是Set存的是單個元素,而Map存的是鍵值對。

    var gifts = {
      // Key:    Value
      'first': 'partridge',
      'second': 'turtledoves',
      'fifth': 'golden rings'  // 最后一個元素后,可以帶逗號,也可以不帶
    };
    
    var gifts = Map();
    gifts['first'] = 'partridge';
    gifts['second'] = 'turtledoves';
    gifts['fifth'] = 'golden rings';
    
    // 使用數(shù)字作為key
    var nobleGases = Map();
    nobleGases[2] = 'helium';
    nobleGases[10] = 'neon';
    nobleGases[18] = 'argon';
    

    Map對象插入值和取值

    除了初始化時對map進行賦值,后續(xù)也可以直接通過key進行賦值。

    var gifts = {'first': 'partridge'};
    gifts['fourth'] = 'calling birds';   // 賦值
    
    assert(gifts['first'] == 'partridge');  // 取值
    
  8. Runne和Symbol,平時沒用到,用到的時候再來補充。

操作符

  1. 操作符就是兩個對象之間相互操作的一些運算操作,比如兩個整數(shù)相加。

  2. 操作符的優(yōu)先級:從左到右,從上到下。

  3. 算數(shù)運算符

    操作符 解釋
    + 相加運算,var a = 1 + 1;
    減號 ,var a = 2 - 1;
    -expr 負號
    * 乘號
    / 相除,5 / 2 的結(jié)果是 2.5
    ~/ 除號,但是返回值為整數(shù)。5 / 2 的結(jié)果是 2 。
    % 取模,相除之后取余數(shù)。
    ++var 變量自動加一。如果前面有賦值語句,那么會先加一后賦值。
    var++ 變量自動加一。如果前面有賦值語句,那么會先賦值后加一。
    --var 變量自動減一。如果前面有賦值語句,那么會先減一后賦值。
    var-- 變量自動減一。如果前面有賦值語句,那么會先賦值后減一。
  4. 關(guān)系運算符

    操作符 解釋
    == 相等。判斷兩個對象x和y是否表示相同的事物, 使用 == 運算符。
    != 不等
    > 大于
    < 小于
    >= 大于等于
    <= 小于等于
  5. 類型運算符

    操作符 解釋
    as 類型轉(zhuǎn)換。a as b將a轉(zhuǎn)換為b;
    is 如果對象是指定的類型返回 True 。例如, obj is Object 總是 true
    is! 如果對象是指定的類型返回 False
  6. 邏輯操作符

    操作符 解釋
    !表達式 對表達式結(jié)果取反(true 變?yōu)?false ,false 變?yōu)?true)
    || 邏輯 OR
    && 邏輯 AND
  7. 條件表達式

    if-else表達式的兩種種簡寫方式。

  8. 三元表達式

  9. 格式為:condition ? 表達式1 : 表達式2

  10. 如果 condition 是 true,執(zhí)行 表達式1 (并返回執(zhí)行的結(jié)果); 否則執(zhí)行 表達式2 `并返回其結(jié)果。

  11. 二元表達式

  12. 格式如下:expr1 ?? expr2

  13. 如果 expr1 是 non-null,返回其值; 否則執(zhí)行 expr2 并返回其結(jié)果。

  14. 級聯(lián)操作符

    級聯(lián)操作符 (..) 可以在同一個對象上 連續(xù)調(diào)用多個函數(shù)以及訪問成員變量。使用級聯(lián)操作符可以避免創(chuàng)建 臨時變量, 并且寫出來的代碼看起來 更加流暢。

    示例代碼

    querySelector('#confirm') // 獲取對象。
      ..text = 'Confirm' // 調(diào)用成員變量。
      ..classes.add('important')
      ..onClick.listen((e) => window.alert('Confirmed!'));
    
    // 等同于下面的代碼
    var button = querySelector('#confirm');
    button.text = 'Confirm';
    button.classes.add('important');
    button.onClick.listen((e) => window.alert('Confirmed!'));
    
    // 嵌套使用級聯(lián)代碼
    final addressBook = (AddressBookBuilder()
          ..name = 'jenny'
          ..email = 'jenny@example.com'
          ..phone = (PhoneNumberBuilder()
                ..number = '415-555-0100'
                ..label = 'home')
              .build())
        .build();
    

控制流

  1. Dart中的控制流分為如下幾種:if-else、for循環(huán)、while循環(huán)、switch、assert

  2. if-else

    和Java完全一樣,直接看demo即可:

    if (isRaining()) {
      you.bringRainCoat();
    } else if (isSnowing()) {
      you.wearJacket();
    } else {
      car.putTopDown();
    }
    
  3. for循環(huán)

    標準寫法

    和Java完全一樣

    var message = StringBuffer('Dart is fun');
    for (var i = 0; i < 5; i++) {
      message.write('!');
    }
    

    for-in迭代寫法

    var collection = [0, 1, 2];
    for (var x in collection) {
      print(x); // 0 1 2
    }
    

    迭代器對象forEach寫法

    實現(xiàn)了 Iterable 接口的對象, 可以使用 forEach()方法

    candidates.forEach((candidate) => candidate.interview());
    

    跳過循環(huán)

    • break:結(jié)束循環(huán);
    • continue:跳過本次循環(huán),開始下次循環(huán);
  4. while循環(huán)

    用法和Java中完全一樣

    while (!isDone()) {
      doSomething();
    }
    
    do {
      printLine();
    } while (!atEndOfPage());
    
  5. switch

    用法和java中的用法完全一直。不過Dart中全部是使用==來進行條件判斷的。

    示例代碼

    var command = 'OPEN';
    switch (command) {
      case 'CLOSED':
      case 'NOW_CLOSED':  // 多個條件可以執(zhí)行同一個條件語句
        executeClosed();
        break;
      case 'OPEN':  // 滿足open條件,執(zhí)行對應(yīng)代碼
        executeOpen();
        break;  // case執(zhí)行結(jié)束要手動調(diào)用break代碼,否則會繼續(xù)向下執(zhí)行。
      default:  // 默認條件
        executeUnknown();
    }
    

    注意:如果沒有滿足的條件,且沒有defalut case,那么會拋異常。

  6. 斷言assert

    通常在自動化測試和單元測試的時候會使用到斷言。在Dart中, assert 語句只在開發(fā)環(huán)境中有效, 在生產(chǎn)環(huán)境是無效的。 Flutter 中的 assert 只在debug 模式中有效。

    使用方法

    assert的使用方法很簡單,傳入一個條件語句:

    • 如果為true就通過,程序正常運行;
    • 如果不為true,正常的程序執(zhí)行流程會被中斷。

    示例代碼

    // 確認變量值小于100。
    assert(number < 100);
    

異常

  1. 拋出異常

  2. 使用方法

  3. throw new FormatException('Expected at least 1 section');  // 拋出一個格式異常
    throw 'Out of llamas!';  // 拋出任意對象
    
  4. 胖箭頭簡寫

  5. 因為拋出異常只有一行,所以可以使用胖箭頭來簡寫

  6. void distanceTo(Point other) => throw UnimplementedError();
    
  7. 捕獲異常 catch

    示例代碼

    try {
      breedMoreLlamas();
    } on OutOfLlamasException {
      // 一個特殊的異常
      buyMoreLlamas();
    } on Exception catch (e) {
      // 其他任何異常
      print('Unknown exception: $e');
    } catch (e) {
      // 沒有指定的類型,處理所有異常
      print('Something really unknown: $e');
    }
    
    • 使用try-catch來嘗試捕獲異常;

    • 使用on來判斷異常的類型;

    • 多個異常就用多個on來判斷異常類型;

    • 不加on則捕獲所有異常

    • 函數(shù) catch() 可以帶有一個或者兩個參數(shù), 第一個參數(shù)為拋出的異常對象, 第二個為堆棧信息 (一個 StackTrace 對象)。

      try {
        // ···
      } on Exception catch (e) {
        print('Exception details:\n $e');
      } catch (e, s) {
        print('Exception details:\n $e');
        print('Stack trace:\n $s');
      }
      

    重新拋出異常

    我們在catch完一個異常后,可能需要把這個異常再次拋出??梢允褂胷ethrow,將之前的異常重新拋出。

    try {
        dynamic foo = true;
        print(foo++); // Runtime error
      } catch (e) {
        print('misbehave() partially handled ${e.runtimeType}.');
        rethrow; // Allow callers to see the exception.
      }
    
  8. Finally

    和java一樣,不管是否拋出異常, finally中的代碼都會被執(zhí)行。

    • 如果 catch 沒有匹配到異常, 異常會在finally執(zhí)行完成后,再次被拋出;
    • 如果有匹配到catch,那么會等匹配的 catch 執(zhí)行完成后,再執(zhí)行finally;
    try {
      breedMoreLlamas();
    } catch (e) {
      print('Error: $e'); // Handle the exception first.
    } finally {
      cleanLlamaStalls(); // Then clean up.
    }
    

參考

Dart 編程語言概覽

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容