內容

以下是 Dart 文件中使用的術語定義。

常數內容

#

常數內容是程式碼中不需要包含 const 關鍵字的區域,因為該區域中的所有內容都必須是常數。下列位置是常數內容

  • const 關鍵字為前綴的清單、對應或集合文字中的所有內容。範例

    dart
    var l = const [/*constant context*/];
  • 常數建構函式呼叫中的引數。範例

    dart
    var p = const Point(/*constant context*/);
  • const 關鍵字為前綴的變數初始化項。範例

    dart
    const v = /*constant context*/;
  • 註解

  • case 子句中的表達式。範例

    dart
    void f(int e) {
      switch (e) {
        case /*constant context*/:
          break;
      }
    }

明確指定

#

明確指派分析是針對程式碼中每個點的每個區域變數,判斷下列哪個為真

  • 變數已明確指派值(明確指派)。
  • 變數已明確未指派值(明確未指派)。
  • 變數可能已指派或未指派值,視為到達該點所採取的執行路徑而定。

明確指派分析有助於找出程式碼中的問題,例如可能未指派值的變數被參照,或只能指派一次值的變數在可能已指派值後再次指派。

例如,在下列程式碼中,將變數 s 傳遞給 print 作為引數時,s 明確未指派

dart
void f() {
  String s;
  print(s);
}

但在下列程式碼中,變數 s 明確指派

dart
void f(String name) {
  String s = 'Hello $name!';
  print(s);
}

明確指派分析甚至可以判斷變數在有多個可能執行路徑時是否明確指派(或未指派)。在下列程式碼中,如果執行通過 if 陳述式的真或假分支,就會呼叫 print 函式,但由於不論採用哪個分支,s 都會被指派,因此在傳遞給 print 之前,它明確已指派

dart
void f(String name, bool casual) {
  String s;
  if (casual) {
    s = 'Hi $name!';
  } else {
    s = 'Hello $name!';
  }
  print(s);
}

在流程分析中,if 陳述式的結尾稱為結合,也就是兩個或多個執行路徑合併回來的點。在結合處,分析會指出,如果變數在所有合併的路徑中都明確指派,則該變數明確指派;如果變數在所有路徑中都明確未指派,則該變數明確未指派。

有時變數會在一個路徑上指派值,但在另一個路徑上不會,這種情況下,變數可能已指派或未指派值。在下列範例中,if 陳述式的真分支可能會執行,也可能不會執行,因此變數可能已指派或未指派值

dart
void f(String name, bool casual) {
  String s;
  if (casual) {
    s = 'Hi $name!';
  }
  print(s);
}

如果有一個未將值指定給 s 的 false 分支,情況也是如此。

迴圈的分析稍微複雜一些,但遵循相同的基本推理。例如,while 迴圈中的條件總是執行,但主體可能執行或不執行。因此,就像 if 陳述式一樣,while 陳述式的結尾有一個連接點,連接條件為 true 的路徑和條件為 false 的路徑。

如需其他詳細資訊,請參閱 明確指定 的規格。

函式

#

除非另有說明,否則術語函式是指頂層函式、區域函式、靜態方法和實例方法。

如需其他詳細資訊,請參閱 函式 的文件。

不可否認的模式

#

不可反駁的模式 是總是相符的模式。不可反駁的模式是唯一可以在不可反駁的內容中出現的模式:宣告指定 模式內容。

混入應用程式

#

混入應用程式 是將混入套用至類別時建立的類別。例如,考量下列宣告

dart
class A {}

mixin M {}

class B extends A with M {}

類別 BM 套用至 A 的混入應用程式的子類別,有時稱為 A+M。類別 A+MA 的子類別,並有從 M 複製的成員。

您可以透過定義混入應用程式來給予實際名稱,定義方式如下

dart
class A {}

mixin M {}

class A_M = A with M;

給定此 A_M 宣告,下列 B 宣告等同於原始範例中的 B 宣告

dart
class B extends A_M {}

覆寫推論

#

覆寫推論是根據要覆寫的方法或方法中對應的類型,推論方法宣告中任何遺失類型的程序。

如果候選方法(遺失類型資訊的方法)覆寫單一繼承方法,則會推論覆寫方法中對應的類型。例如,考量下列程式碼

dart
class A {
  int m(String s) => 0;
}

class B extends A {
  @override
  m(s) => 1;
}

B 中的 m 宣告是候選方法,因為它遺失回傳類型和參數類型。由於它覆寫單一方法(A 中的 m 方法),因此會使用覆寫方法中的類型來推論遺失的類型,而 B 中的方法會像宣告為 int m(String s) => 1; 一樣。

如果候選方法覆寫多個方法,且其中一個覆寫方法 Ms 的函式類型是所有其他覆寫方法函式類型的超類型,則會使用 Ms 來推論遺失的類型。例如,考量下列程式碼

dart
class A {
  int m(num n) => 0;
}

class B {
  num m(int i) => 0;
}

class C implements A, B {
  @override
  m(n) => 1;
}

C 中的 m 宣告是覆寫推論的候選方法,因為它遺失回傳類型和參數類型。它覆寫 A 中的 mB 中的 m,因此我們需要從中選擇一個來推論遺失的類型。但由於 Am 的函式類型(int Function(num))是 Bm 的函式類型(num Function(int))的超類型,因此會使用 A 中的函式來推論遺失的類型。結果與將 C 中的方法宣告為 int m(num n) => 1; 相同。

如果沒有任何覆寫方法的函式類型是所有其他覆寫方法的超類型,則會產生錯誤。

部分檔案

#

部分檔案是包含 part of 指令的 Dart 原始檔。有關使用指南,請參閱 有效 Dart 條目。

可能為非 Null

#

如果類型明確為非可為空或為類型參數,則該類型可能為非可為空

如果類型名稱後未接問號,則該類型明確為非可為空。請注意,有些類型永遠為可為空,例如 Nulldynamic,而 FutureOr 僅在後未接問號類型引數為非可為空 (例如 FutureOr<String>) 時才為非可為空。

類型參數可能為非可為空,因為實際執行時期類型 (指定為類型引數的類型) 可能為非可為空。例如,針對 class C<T> {} 的宣告,類型 C 可搭配非可為空類型引數使用,例如 C<int>

公開函式庫

#

公開函式庫是位於套件的 lib 目錄內但不在 lib/src 目錄內的函式庫。

可否認的模式

#

可反駁模式是一種可以針對值進行測試的模式,以判斷模式是否與值相符。如果不符,模式會反駁或否定相符。可反駁模式出現在 相符內容 中。