1. 程式人生 > 實用技巧 >Dart 關鍵字【2】

Dart 關鍵字【2】

想要寫好Flutter,那麼對Dart的基本關鍵字的掌握是必不可少的,今天就再探究一下其他的關鍵字。

as is si!

as is is!,運算子用於執行時處理型別檢查:

obj實現了T的介面時,obj is Ttrue,obj as T可以將obj 型別轉換成T型別:


class Person {
  void play(){
    print('person');
  }
}
class PersonSub extends Person{}
class Person2 {
    void play(){
    print('person2');
  }
}

 Person person = PersonSub();
 if(person is Person2){
 (person as Person2).play();
 }
 if(person is PersonSub){
   (person as PersonSub).play();
 }

person型別是Person2執行第一個if函式,如果直接(person as Person2).play();,則會崩潰,每次轉換型別的時候,提交校驗a is T是有必要的。

enum

列舉型別也稱為 enumerationsenums , 是一種特殊的類,用於表示數量固定的常量值。

throw catch on final rethrow

捕獲異常可以避免異常繼續傳遞(除非重新丟擲(rethrow )異常)。 可以通過捕獲異常的機會來處理該異常:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

通過指定多個 catch 語句,可以處理可能丟擲多種型別異常的程式碼。 與丟擲異常型別匹配的第一個 catch 語句處理異常。 如果 catch 語句未指定型別, 則該語句可以處理任何型別的丟擲物件:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // 一個特殊的異常
  buyMoreLlamas();
} on Exception catch (e) {
  // 其他任何異常
  print('Unknown exception: $e');
} catch (e) {
  // 沒有指定的型別,處理所有異常
  print('Something really unknown: $e');
}

如上述程式碼所示,捕獲語句中可以同時使用 oncatch ,也可以單獨分開使用。 使用 on 來指定異常型別, 使用 catch 來 捕獲異常物件。

catch() 函式可以指定1到2個引數, 第一個引數為丟擲的異常物件, 第二個為堆疊資訊 ( 一個 StackTrace 物件 )。

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

如果僅需要部分處理異常, 那麼可以使用關鍵字 rethrow 將異常重新丟擲。

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

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}

不管是否丟擲異常, finally 中的程式碼都會被執行。 如果 catch 沒有匹配到異常, 異常會在 finally 執行完成後,再次被丟擲:

try {
  breedMoreLlamas();
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}

任何匹配的 catch 執行完成後,再執行 finally

try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

factory

當執行建構函式並不總是建立這個類的一個新例項時,則使用 factory 關鍵字。 例如,一個工廠建構函式可能會返回一個 cache 中的例項, 或者可能返回一個子類的例項。

以下示例演示了從快取中返回物件的工廠建構函式:

class Logger {
  final String name;
  bool mute = false;

  // 從命名的 _ 可以知,
  // _cache 是私有屬性。
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

const

使用過程中從來不會被修改的變數, 可以使用 final 或 const, 而不是 var 或者其他型別, Final 變數的值只能被設定一次; Const 變數在編譯時就已經固定 (Const 變數 是隱式 Final 的型別.) 最高階 final 變數或類變數在第一次使用時被初始化。

提示: 例項變數可以是 final 型別但不能是 const 型別。 必須在建構函式體執行之前初始化 final 例項變數 —— 在變數宣告中,引數建構函式中或建構函式的初始化列表中進行初始化。

建立和設定一個 Final 變數:

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';

final 不能被修改:

name = 'Alice'; // Error: 一個 final 變數只能被設定一次。

如果需要在編譯時就固定變數的值,可以使用 const 型別變數。 如果 Const 變數是類級別的,需要標記為 static const。 在這些地方可以使用在編譯時就已經固定不變的值,字面量的數字和字串, 固定的變數,或者是用於計算的固定數字:

const bar = 1000000; // 壓力單位 (dynes/cm2)
const double atm = 1.01325 * bar; // 標準氣壓

operator

重寫運算子,下面的運算子可以被重寫。

< + | []
> / ^ []
<= ~/ & ~
>= * << ==
% >>

提示: 你可能會被提示 != 運算子為非可過載運算子。 因為 e1 != e2 表示式僅僅是 !(e1 == e2) 的語法糖。

下面示例演示一個類重寫 + 和 - 操作符:

class Vector {
  final int x, y;

  Vector(this.x, this.y);

  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

  // 運算子 == 和 hashCode 部分沒有列出。 有關詳情,請參考下面的註釋。
  // ···
}

void main() {
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  assert(v + w == Vector(4, 5));
  assert(v - w == Vector(0, 1));
}

如果要重寫 == 操作符,需要重寫物件的 hashCode getter 方法。 重寫 == 和 hashCode 的例項,參考 Implementing map keys.

part part of

covariant

Function

Dart 是一門真正面向物件的語言, 甚至其中的函式也是物件,並且有它的型別 Function 。 這也意味著函式可以被賦值給變數或者作為引數傳遞給其他函式。 也可以把 Dart 類的例項當做方法來呼叫。 有關更多資訊,參考 Callable classes.

已下是函式實現的示例:

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

雖然在 Effective Dart 中推薦 公共API中宣告型別, 但是省略了型別宣告,函式依舊是可以正常使用的:

isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

如果函式中只有一句表示式,可以使用簡寫語法:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
=> expr 語法是 { return expr; } 的簡寫。 => 符號 有時也被稱為 箭頭 語法。

提示: 在箭頭 (=>) 和分號 (