跳到主要內容
目錄

診斷訊息

目錄 keyboard_arrow_down keyboard_arrow_up
更多水平

本頁列出 Dart 分析器產生的診斷訊息,其中詳細說明這些訊息的意義以及如何修正程式碼。如需分析器的詳細資訊,請參閱自訂靜態分析

診斷

#

分析器會針對不符合語言規格或可能以非預期方式運作的程式碼產生下列診斷訊息。

abi_specific_integer_invalid

#

擴充 'AbiSpecificInteger' 的類別必須剛好有一個 const 建構子、沒有其他成員,且沒有類型參數。

描述

#

當擴充 AbiSpecificInteger 的類別不符合以下所有需求時,分析器會產生此診斷訊息

  • 必須剛好有一個建構子
  • 建構子必須標記為 const
  • 除了建構子之外,不得有任何其他成員
  • 不得有任何類型參數

範例

#

下列程式碼會產生此診斷訊息,因為類別 C 未定義 const 建構子

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
}

下列程式碼會產生此診斷訊息,因為建構子不是 const 建構子

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
  C();
}

下列程式碼會產生此診斷訊息,因為類別 C 定義了多個建構子

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
  const C.zero();
  const C.one();
}

下列程式碼會產生此診斷訊息,因為類別 C 定義了一個欄位

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
  final int i;

  const C(this.i);
}

下列程式碼會產生此診斷訊息,因為類別 C 具有類型參數

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C<T> extends AbiSpecificInteger { // type parameters
  const C();
}

常見修正方式

#

變更類別,使其符合沒有類型參數且只有一個成員(即 const 建構子)的需求

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
  const C();
}

abi_specific_integer_mapping_extra

#

擴充 'AbiSpecificInteger' 的類別必須剛好有一個 'AbiSpecificIntegerMapping' 註解,指定從 ABI 到具有固定大小的 'NativeType' 整數的對應。

描述

#

當擴充 AbiSpecificInteger 的類別具有多個 AbiSpecificIntegerMapping 註解時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息,因為類別 C 上有兩個 AbiSpecificIntegerMapping 註解

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
@AbiSpecificIntegerMapping({Abi.linuxX64 : Uint16()})
final class C extends AbiSpecificInteger {
  const C();
}

常見修正方式

#

移除除一個註解之外的所有註解,並視情況合併引數

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8(), Abi.linuxX64 : Uint16()})
final class C extends AbiSpecificInteger {
  const C();
}

abi_specific_integer_mapping_missing

#

擴充 'AbiSpecificInteger' 的類別必須剛好有一個 'AbiSpecificIntegerMapping' 註解,指定從 ABI 到具有固定大小的 'NativeType' 整數的對應。

描述

#

當擴充 AbiSpecificInteger 的類別沒有 AbiSpecificIntegerMapping 註解時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息,因為類別 C 上沒有 AbiSpecificIntegerMapping 註解

dart
import 'dart:ffi';

final class C extends AbiSpecificInteger {
  const C();
}

常見修正方式

#

AbiSpecificIntegerMapping 註解新增至類別

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
  const C();
}

abi_specific_integer_mapping_unsupported

#

對 '{0}' 的無效對應;僅支援對 'Int8'、'Int16'、'Int32'、'Int64'、'Uint8'、'Uint16'、'UInt32' 和 'Uint64' 的對應。

描述

#

AbiSpecificIntegerMapping 註解的 map 引數中的值不是下列整數類型之一時,分析器會產生此診斷訊息

  • Int8
  • Int16
  • Int32
  • Int64
  • Uint8
  • Uint16
  • UInt32
  • Uint64

範例

#

下列程式碼會產生此診斷訊息,因為 map 條目的值是 Array<Uint8>,這不是有效的整數類型

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Array<Uint8>(4)})
final class C extends AbiSpecificInteger {
  const C();
}

常見修正方式

#

使用其中一個有效類型作為 map 中的值

dart
import 'dart:ffi';

@AbiSpecificIntegerMapping({Abi.macosX64 : Int8()})
final class C extends AbiSpecificInteger {
  const C();
}

抽象_欄位_初始化器

#

抽象欄位不能有初始化器。

描述

#

當具有 abstract 修飾詞的欄位也有初始化器時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息,因為 f 標記為 abstract 且具有初始化器

dart
abstract class C {
  abstract int f = 0;
}

下列程式碼會產生此診斷訊息,因為 f 標記為 abstract 且建構子中有初始化器

dart
abstract class C {
  abstract int f;

  C() : f = 0;
}

常見修正方式

#

如果欄位必須是抽象的,則移除初始化器

dart
abstract class C {
  abstract int f;
}

如果欄位不需要是抽象的,則移除關鍵字

dart
abstract class C {
  int f = 0;
}

抽象_sealed_類別

#

'sealed' 類別不能標記為 'abstract',因為它已經隱含地是抽象的。

描述

#

當使用 abstract 修飾詞和 sealed 修飾詞宣告類別時,分析器會產生此診斷訊息。密封類別隱含地是抽象的,因此不允許明確地同時使用這兩個修飾詞。

範例

#

下列程式碼會產生此診斷訊息,因為類別 C 同時使用 abstractsealed 宣告

dart
abstract sealed class C {}

常見修正方式

#

如果類別應該是抽象的但不是密封的,則移除 sealed 修飾詞

dart
abstract class C {}

如果類別應該同時是抽象的和密封的,則移除 abstract 修飾詞

dart
sealed class C {}

抽象_父類別_成員_參考

#

父類型中的 {0} '{1}' 永遠是抽象的。

描述

#

當使用 super 參考繼承的成員,但父類別鏈中沒有成員的具體實作時,分析器會產生此診斷訊息。抽象成員無法叫用。

範例

#

下列程式碼會產生此診斷訊息,因為 B 未繼承 a 的具體實作

dart
abstract class A {
  int get a;
}
class B extends A {
  int get a => super.a;
}

常見修正方式

#

移除抽象成員的叫用,可能以叫用具體成員取代。

不明確的_匯出

#

名稱 '{0}' 定義於程式庫 '{1}' 和 '{2}' 中。

描述

#

當兩個或多個匯出指示詞導致從多個程式庫匯出相同的名稱時,分析器會產生此診斷訊息。

範例

#

假設檔案 a.dart 包含

dart
class C {}

以及檔案 b.dart 包含

dart
class C {}

下列程式碼會產生此診斷訊息,因為名稱 C 同時從 a.dartb.dart 匯出

dart
export 'a.dart';
export 'b.dart';

常見修正方式

#

如果其中一個程式庫中的名稱都不需要匯出,則移除不必要的匯出指示詞

dart
export 'a.dart';

如果所有匯出指示詞都是必要的,則在除一個指示詞之外的所有指示詞中隱藏名稱

dart
export 'a.dart';
export 'b.dart' hide C;

不明確的_擴充功能_成員_存取

#

名為 '{0}' 的成員定義於 '{1}' 和 '{2}' 中,且兩者都不更具體。

名為 '{0}' 的成員定義於 {1} 中,且沒有任何一個更具體。

描述

#

當程式碼參考物件的成員(例如,o.m()o.mo[i]),其中 o 的靜態類型未宣告成員(例如 m[])時,分析器會嘗試在擴充功能中尋找成員。例如,如果成員是 m,則分析器會尋找宣告名為 m 的成員且具有 o 的靜態類型可賦值給的擴充類型之擴充功能。當範圍內有多個此類擴充功能時,會選取擴充類型最具體的擴充功能。

當沒有任何擴充功能的擴充類型比所有其他擴充功能的擴充類型更具體時,分析器會產生此診斷訊息,使得成員的參考不明確。

範例

#

下列程式碼會產生此診斷訊息,因為無法在 E1 中的成員和 E2 中的成員之間做出選擇

dart
extension E1 on String {
  int get charCount => 1;
}

extension E2 on String {
  int get charCount => 2;
}

void f(String s) {
  print(s.charCount);
}

常見修正方式

#

如果您不需要兩個擴充功能,則可以刪除或隱藏其中一個。

如果您需要兩個擴充功能,則使用擴充功能覆寫明確選取您想要使用的擴充功能

dart
extension E1 on String {
  int get charCount => length;
}

extension E2 on String {
  int get charCount => length;
}

void f(String s) {
  print(E2(s).charCount);
}

不明確的_匯入

#

名稱 '{0}' 定義於程式庫 {1} 中。

描述

#

當參考的名稱在兩個或多個匯入的程式庫中宣告時,分析器會產生此診斷訊息。

範例

#

假設一個程式庫 (a.dart) 定義一個類別 (本範例中的 C)

dart
class A {}
class C {}

以及一個程式庫 (b.dart) 定義一個具有相同名稱的不同類別

dart
class B {}
class C {}

下列程式碼會產生此診斷訊息

dart
import 'a.dart';
import 'b.dart';

void f(C c1, C c2) {}

常見修正方式

#

如果不需要任何程式庫,則移除其匯入指示詞

dart
import 'a.dart';

void f(C c1, C c2) {}

如果名稱仍然由多個程式庫定義,則將 hide 子句新增至除一個程式庫之外的所有程式庫的匯入指示詞

dart
import 'a.dart' hide C;
import 'b.dart';

void f(C c1, C c2) {}

如果您必須能夠參考多個這些類型,則為每個匯入指示詞新增前置詞,並使用適當的前置詞限定參考

dart
import 'a.dart' as a;
import 'b.dart' as b;

void f(a.C c1, b.C c2) {}

不明確的_set或_map_字面值_兩者皆是

#

字面值不能是 map 或 set,因為它至少包含一個字面值 map 條目或展開運算子展開 'Map',以及至少一個不是這些的元素。

描述

#

由於 map 和 set 字面值使用相同的分隔符號({}),因此分析器會查看類型引數和元素,以判斷您意指的字面值種類。當沒有類型引數時,分析器會使用元素的類型。如果所有元素都是字面值 map 條目,且所有展開運算子都在展開 Map,則它是 Map。如果沒有任何元素是字面值 map 條目,且所有展開運算子都在展開 Iterable,則它是 Set。如果這兩者都不成立,則不明確。

當至少一個元素是字面值 map 條目或展開運算子展開 Map,且至少一個元素不是這些時,分析器會產生此診斷訊息,使得分析器無法判斷您正在撰寫 map 字面值還是 set 字面值。

範例

#

下列程式碼會產生此診斷訊息

dart
union(Map<String, String> a, List<String> b, Map<String, String> c) =>
    {...a, ...b, ...c};

清單 b 只能展開到 set 中,而 map ac 只能展開到 map 中,且字面值不能同時是兩者。

常見修正方式

#

有兩種常見的方法可以解決這個問題。第一種方法是移除所有種類的展開元素,使元素保持一致。在這種情況下,這可能意味著移除列表,並決定如何處理現在未使用的參數。

dart
union(Map<String, String> a, List<String> b, Map<String, String> c) =>
    {...a, ...c};

第二種解決方法是將其中一種元素更改為與其他元素一致的元素。例如,您可以將列表的元素添加為鍵,並將它們映射到自身。

dart
union(Map<String, String> a, List<String> b, Map<String, String> c) =>
    {...a, for (String s in b) s: s, ...c};

不明確的_set或_map_字面值_兩者擇一

#

這個字面值必須是 map 或 set,但元素沒有足夠的資訊來進行型別推斷。

描述

#

因為 map 和 set 字面值使用相同的分隔符號 ({}),所以分析器會查看型別引數和元素,以判斷您指的是哪種字面值。當沒有型別引數且所有元素都是展開元素(這在兩種字面值中都允許)時,分析器會使用正在展開的表達式的型別。如果所有表達式都具有 Iterable 型別,則它是 set 字面值;如果它們都具有 Map 型別,則它是 map 字面值。

當展開的表達式都沒有允許分析器判斷您正在編寫 map 字面值還是 set 字面值的型別時,就會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息

dart
union(a, b) => {...a, ...b};

問題發生是因為沒有型別引數,並且沒有關於 ab 型別的資訊。

常見修正方式

#

有三種常見的方法可以解決這個問題。第一種方法是向字面值添加型別引數。例如,如果字面值旨在成為 map 字面值,您可以這樣寫

dart
union(a, b) => <String, String>{...a, ...b};

第二種解決方法是添加型別資訊,使表達式具有 Iterable 型別或 Map 型別。您可以添加顯式轉換,或者在這種情況下,為兩個參數的宣告添加型別。

dart
union(List<int> a, List<int> b) => {...a, ...b};

第三種解決方法是添加上下文資訊。在這種情況下,這意味著為函數添加回傳型別。

dart
Set<String> union(a, b) => {...a, ...b};

在其他情況下,您可能在其他地方添加型別。例如,假設原始程式碼如下所示

dart
union(a, b) {
  var x = {...a, ...b};
  return x;
}

您可以像這樣在 x 上添加型別註解

dart
union(a, b) {
  Map<String, String> x = {...a, ...b};
  return x;
}

指標_欄位上的_註解

#

結構 (struct) 類別中型別為 'Pointer' 的欄位不應有任何註解。

描述

#

當在 Struct 子類別中宣告且型別為 Pointer 的欄位也帶有相關的註解時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為欄位 p 的型別為 Pointer,並且在 Struct 的子類別中宣告,但帶有註解 @Double()

dart
import 'dart:ffi';

final class C extends Struct {
  @Double()
  external Pointer<Int8> p;
}

常見修正方式

#

從欄位中移除註解

dart
import 'dart:ffi';

final class C extends Struct {
  external Pointer<Int8> p;
}

引數必須是常數

#

引數 '{0}' 必須是常數。

描述

#

Pointer.asFunctionDynamicLibrary.lookupFunction 的調用具有 isLeaf 引數,但其值不是常數表達式時,分析器會產生此診斷訊息。

Pointer.fromFunctionNativeCallable.isolateLocal 的調用具有 exceptionalReturn 引數,但其值不是常數表達式時,分析器也會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為 isLeaf 引數的值是一個參數,因此不是常數。

dart
import 'dart:ffi';

int Function(int) fromPointer(
    Pointer<NativeFunction<Int8 Function(Int8)>> p, bool isLeaf) {
  return p.asFunction(isLeaf: isLeaf);
}

常見修正方式

#

如果有適合使用的常數,則將引數替換為常數。

dart
import 'dart:ffi';

const isLeaf = false;

int Function(int) fromPointer(Pointer<NativeFunction<Int8 Function(Int8)>> p) {
  return p.asFunction(isLeaf: isLeaf);
}

如果沒有適合的常數,則將引數替換為布林字面值。

dart
import 'dart:ffi';

int Function(int) fromPointer(Pointer<NativeFunction<Int8 Function(Int8)>> p) {
  return p.asFunction(isLeaf: true);
}

引數必須是原生

#

'Native.addressOf' 的引數必須使用 @Native 註解。

描述

#

當傳遞給 Native.addressOf 的引數未使用 Native 註解時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 addressOf 的引數是一個字串,而不是欄位,而字串不能被註解。

dart
import 'dart:ffi';

@Native<Void Function()>()
external void f();

void g() {
  print(Native.addressOf('f'));
}

以下程式碼產生此診斷訊息,因為函數 f 被傳遞給 addressOf,但未註解為 Native

dart
import 'dart:ffi';

external void f();

void g() {
  print(Native.addressOf<NativeFunction<Void Function()>>(f));
}

常見修正方式

#

如果引數既不是欄位也不是函數,則將引數替換為使用 Native 註解的欄位或函數。

dart
import 'dart:ffi';

@Native<Void Function()>()
external void f();

void g() {
  print(Native.addressOf<NativeFunction<Void Function()>>(f));
}

如果引數是欄位或函數,則使用 Native 註解欄位或函數。

dart
import 'dart:ffi';

@Native<Void Function()>()
external void f();

void g() {
  print(Native.addressOf<NativeFunction<Void Function()>>(f));
}

引數類型不可賦值

#

引數型別 '{0}' 無法指派給參數型別 '{1}'。{2}

描述

#

當引數的靜態型別無法指派給對應參數的靜態型別時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 num 無法指派給 String

dart
String f(String x) => x;
String g(num y) => f(y);

常見修正方式

#

如果可能,請重寫程式碼,使靜態型別可指派。在上面的範例中,您或許可以更改參數 y 的型別。

dart
String f(String x) => x;
String g(String y) => f(y);

如果無法進行該修正,則添加程式碼來處理引數值不是所需型別的情況。一種方法是將其他型別強制轉換為所需的型別。

dart
String f(String x) => x;
String g(num y) => f(y.toString());

另一種方法是添加顯式型別測試和後備程式碼。

dart
String f(String x) => x;
String g(Object y) => f(y is String ? y : '');

如果您認為引數的執行時期型別將始終與參數的靜態型別相同,並且您願意承擔在錯誤時執行時期拋出例外狀況的風險,則添加顯式轉換。

dart
String f(String x) => x;
String g(num y) => f(y as String);

引數類型不可賦值給錯誤處理常式

#

引數型別 '{0}' 無法指派給參數型別 '{1} Function(Object)' 或 '{1} Function(Object, StackTrace)'。

描述

#

Future.catchError 的調用具有一個引數,該引數是一個函數,其參數與在調用函數時將傳遞給函數的引數不相容時,分析器會產生此診斷訊息。 catchError 第一個引數的靜態型別只是 Function,即使傳入的函數預期具有型別為 Object 的單個參數,或型別為 ObjectStackTrace 的兩個參數。

範例

#

以下程式碼產生此診斷訊息,因為傳遞給 catchError 的閉包不接受任何參數,但函數需要至少接受一個參數。

dart
void f(Future<int> f) {
  f.catchError(() => 0);
}

以下程式碼產生此診斷訊息,因為傳遞給 catchError 的閉包接受三個參數,但它不能有超過兩個的必要參數。

dart
void f(Future<int> f) {
  f.catchError((one, two, three) => 0);
}

以下程式碼產生此診斷訊息,因為即使傳遞給 catchError 的閉包接受一個參數,但閉包的型別與 Object 不相容。

dart
void f(Future<int> f) {
  f.catchError((String error) => 0);
}

常見修正方式

#

更改傳遞給 catchError 的函數,使其具有一個或兩個必要參數,並且參數具有所需的型別。

dart
void f(Future<int> f) {
  f.catchError((Object error) => 0);
}

重新導向建構子中的_assert

#

重新導向建構子不能有 'assert' 初始化子。

描述

#

當重新導向建構子(重新導向到同一類別中另一個建構子的建構子)在初始化列表中具有 assert 時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為未命名的建構子是重新導向建構子,並且在初始化列表中也具有 assert。

dart
class C {
  C(int x) : assert(x > 0), this.name();
  C.name() {}
}

常見修正方式

#

如果不需要 assert,則將其移除。

dart
class C {
  C(int x) : this.name();
  C.name() {}
}

如果需要 assert,則將建構子轉換為工廠建構子。

dart
class C {
  factory C(int x) {
    assert(x > 0);
    return C.name();
  }
  C.name() {}
}

資源目錄不存在

#

資源目錄 '{0}' 不存在。

描述

#

當資源列表包含引用不存在目錄的值時,分析器會產生此診斷訊息。

範例

#

假設目錄 assets 不存在,則以下程式碼產生此診斷訊息,因為它被列為包含資源的目錄。

yaml
name: example
flutter:
  assets:
    - assets/

常見修正方式

#

如果路徑正確,則在該路徑建立一個目錄。

如果路徑不正確,則更改路徑以匹配包含資源的目錄的路徑。

資源不存在

#

資源檔案 '{0}' 不存在。

描述

#

當資源列表包含引用不存在檔案的值時,分析器會產生此診斷訊息。

範例

#

假設檔案 doesNotExist.gif 不存在,則以下程式碼產生此診斷訊息,因為它被列為資源。

yaml
name: example
flutter:
  assets:
    - doesNotExist.gif

常見修正方式

#

如果路徑正確,則在該路徑建立一個檔案。

如果路徑不正確,則更改路徑以匹配包含資源的檔案的路徑。

資源欄位不是清單

#

'assets' 欄位的值預期為相對檔案路徑的列表。

描述

#

assets 鍵的值不是列表時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 assets 鍵的值是一個字串,但預期為列表。

yaml
name: example
flutter:
  assets: assets/

常見修正方式

#

更改資源列表的值,使其成為列表。

yaml
name: example
flutter:
  assets:
    - assets/

資源遺失路徑

#

資源映射條目必須包含 'path' 欄位。

描述

#

當資源映射缺少 path 值時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為資源映射缺少 path 值。

yaml
name: example
flutter:
  assets:
    - flavors:
      - premium

常見修正方式

#

更改資源映射,使其包含具有字串值(有效的 POSIX 風格檔案路徑)的 path 欄位。

yaml
name: example
flutter:
  assets:
    - path: assets/image.gif
      flavors:
      - premium

資源不是字串

#

資源必須是檔案路徑(字串)。

描述

#

assets 列表包含不是字串的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 assets 列表包含一個映射。

yaml
name: example
flutter:
  assets:
    - image.gif: true

常見修正方式

#

更改 assets 列表,使其僅包含有效的 POSIX 風格檔案路徑。

yaml
name: example
flutter:
  assets:
    - assets/image.gif

資源不是字串或 Map

#

資源值必須是檔案路徑(字串)或映射。

描述

#

當資源值不是字串或映射時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為資源值是一個列表。

yaml
name: example
flutter:
  assets:
    - [one, two, three]

常見修正方式

#

如果您需要指定的不僅僅是資源的路徑,則將該值替換為具有 path 鍵(有效的 POSIX 風格檔案路徑)的映射。

yaml
name: example
flutter:
  assets:
    - path: assets/image.gif
      flavors:
      - premium

如果您只需要指定路徑,則將該值替換為資源的路徑(有效的 POSIX 風格檔案路徑)。

yaml
name: example
flutter:
  assets:
    - assets/image.gif

資源路徑不是字串

#

資源路徑必須是檔案路徑(字串)。

描述

#

當資源映射包含不是字串的 path 值時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為資源映射包含一個 path 值,該值是一個列表。

yaml
name: example
flutter:
  assets:
    - path: [one, two, three]
      flavors:
      - premium

常見修正方式

#

更改 asset 映射,使其包含一個 path 值,該值是一個字串(有效的 POSIX 風格檔案路徑)。

yaml
name: example
flutter:
  assets:
    - path: image.gif
      flavors:
      - premium

請勿儲存的賦值

#

'{0}' 標記為 'doNotStore',不應指派給欄位或頂層變數。

描述

#

當函數(包括方法和 getter)的值(明確或隱含地標記為 doNotStore 註解)儲存在欄位或頂層變數中時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為函數 f 的值正在儲存在頂層變數 x 中。

dart
import 'package:meta/meta.dart';

@doNotStore
int f() => 1;

var x = f();

常見修正方式

#

將對欄位或變數的引用替換為產生值的函數的調用。

賦值給_const

#

常數變數在初始化後不能被指派值。

描述

#

當分析器找到對具有 const 修飾符的頂層變數、靜態欄位或區域變數的指派時,會產生此診斷訊息。編譯時期常數的值在執行時期不能被更改。

範例

#

以下程式碼產生此診斷訊息,因為即使 c 具有 const 修飾符,仍被指派值。

dart
const c = 0;

void f() {
  c = 1;
  print(c);
}

常見修正方式

#

如果變數必須可指派,則移除 const 修飾符。

dart
var c = 0;

void f() {
  c = 1;
  print(c);
}

如果常數不應被更改,則移除指派,或使用區域變數代替對常數的引用。

dart
const c = 0;

void f() {
  var v = 1;
  print(v);
}

賦值給_final

#

'{0}' 不能用作 setter,因為它是 final。

描述

#

當分析器找到 setter 的調用,但由於同名的欄位宣告為 finalconst 而沒有 setter 時,會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 v 是 final。

dart
class C {
  final v = 0;
}

f(C c) {
  c.v = 1;
}

常見修正方式

#

如果您需要能夠設定欄位的值,則從欄位中移除修飾符 final

dart
class C {
  int v = 0;
}

f(C c) {
  c.v = 1;
}

賦值給_final_區域變數

#

final 變數 '{0}' 只能設定一次。

描述

#

當宣告為 final 的區域變數在初始化後被指派值時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 x 是 final,因此在初始化後不能再指派值給它。

dart
void f() {
  final x = 0;
  x = 3;
  print(x);
}

常見修正方式

#

移除關鍵字 final,如果沒有型別註解,則替換為 var

dart
void f() {
  var x = 0;
  x = 3;
  print(x);
}

賦值給沒有_setter的_final

#

類別 '{1}' 中沒有名為 '{0}' 的 setter。

描述

#

當找到對 setter 的引用時,分析器會產生此診斷訊息;該型別沒有定義 setter;但存在具有相同名稱的 getter。

範例

#

以下程式碼產生此診斷訊息,因為 C 中沒有名為 x 的 setter,但存在名為 x 的 getter。

dart
class C {
  int get x => 0;
  set y(int p) {}
}

void f(C c) {
  c.x = 1;
}

常見修正方式

#

如果您想調用現有的 setter,則更正名稱。

dart
class C {
  int get x => 0;
  set y(int p) {}
}

void f(C c) {
  c.y = 1;
}

如果您想調用 setter 但它尚不存在,則宣告它。

dart
class C {
  int get x => 0;
  set x(int p) {}
  set y(int p) {}
}

void f(C c) {
  c.x = 1;
}

賦值給函式

#

函數不能被指派值。

描述

#

當函數的名稱出現在指派表達式的左側時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為對函數 f 的指派無效。

dart
void f() {}

void g() {
  f = () {};
}

常見修正方式

#

如果右側應該指派給其他東西,例如區域變數,則更改左側。

dart
void f() {}

void g() {
  var x = () {};
  print(x);
}

如果目的是更改函數的實作,則定義一個函數值變數而不是函數。

dart
void Function() f = () {};

void g() {
  f = () {};
}

賦值給方法

#

方法不能被指派值。

描述

#

當指派的目標是方法時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 f 不能被指派值,因為它是一個方法。

dart
class C {
  void f() {}

  void g() {
    f = null;
  }
}

常見修正方式

#

重寫程式碼,使其沒有對方法的指派。

賦值給類型

#

型別不能被指派值。

描述

#

當型別名稱的名稱出現在指派表達式的左側時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為對類別 C 的指派無效。

dart
class C {}

void f() {
  C = null;
}

常見修正方式

#

如果右側應該指派給其他東西,例如區域變數,則更改左側。

dart
void f() {}

void g() {
  var c = null;
  print(c);
}

錯誤情境中的_async_for-in

#

async for-in 迴圈只能在 async 函數中使用。

描述

#

當在函數或方法中找到 async for-in 迴圈,但函數或方法的主體未標記為 asyncasync* 時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 f 的主體未標記為 asyncasync*,但 f 包含 async for-in 迴圈。

dart
void f(list) {
  await for (var e in list) {
    print(e);
  }
}

常見修正方式

#

如果函數應回傳 Future,則將主體標記為 async

dart
Future<void> f(list) async {
  await for (var e in list) {
    print(e);
  }
}

如果函數應回傳值的 Stream,則將主體標記為 async*

dart
Stream<void> f(list) async* {
  await for (var e in list) {
    print(e);
  }
}

如果函數應為同步的,則移除迴圈之前的 await

dart
void f(list) {
  for (var e in list) {
    print(e);
  }
}

延遲_區域變數_初始化器中的_await

#

'await' 表達式不能用於 'late' 區域變數的初始化子。

描述

#

當具有 late 修飾符的區域變數在其初始化子中使用 await 表達式時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 await 表達式用於 v 的初始化子中,而 v 是一個標記為 late 的區域變數。

dart
Future<int> f() async {
  late var v = await 42;
  return v;
}

常見修正方式

#

如果可以重寫初始化子以不使用 await,則重寫它。

dart
Future<int> f() async {
  late var v = 42;
  return v;
}

如果無法重寫初始化子,則移除 late 修飾符。

dart
Future<int> f() async {
  var v = await 42;
  return v;
}

不相容類型的_await

#

'await' 表達式不能用於擴展型別 (extension type) 的表達式,該擴展型別不是 'Future' 的子型別。

描述

#

await 表達式中表達式的型別是擴展型別,並且該擴展型別不是 Future 的子類別時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為擴展型別 E 不是 Future 的子類別。

dart
extension type E(int i) {}

void f(E e) async {
  await e;
}

常見修正方式

#

如果擴展型別定義正確,則移除 await

dart
extension type E(int i) {}

void f(E e) {
  e;
}

如果擴展型別旨在是可等待的,則將 Future(或 Future 的子型別)添加到 implements 子句中(如果尚不存在 implements 子句,則添加一個),並使表示型別匹配。

dart
extension type E(Future<int> i) implements Future<int> {}

void f(E e) async {
  await e;
}

函式主體可能正常完成

#

主體可能會正常完成,導致回傳 'null',但回傳型別 '{0}' 是潛在的非可空型別。

描述

#

當方法或函數具有 潛在的非可空 回傳型別,但如果控制流程到達函數末尾,則會隱含地回傳 null 時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為方法 m 在方法末尾插入了 null 的隱含回傳,但該方法被宣告為不回傳 null

dart
class C {
  int m(int t) {
    print(t);
  }
}

以下程式碼產生此診斷訊息,因為方法 m 在方法末尾插入了 null 的隱含回傳,但由於類別 C 可以使用非可空型別引數實例化,因此該方法實際上被宣告為不回傳 null

dart
class C<T> {
  T m(T t) {
    print(t);
  }
}

常見修正方式

#

如果存在可以回傳的合理值,則在方法末尾添加 return 語句。

dart
class C<T> {
  T m(T t) {
    print(t);
    return t;
  }
}

如果方法不會到達隱含回傳,則在方法末尾添加 throw

dart
class C<T> {
  T m(T t) {
    print(t);
    throw '';
  }
}

如果方法有意在末尾回傳 null,則在方法末尾添加顯式的 null 回傳,並更改回傳型別,使其可以有效地回傳 null

dart
class C<T> {
  T? m(T t) {
    print(t);
    return null;
  }
}

函式主體可能正常完成_catchError

#

此 'onError' 處理器必須回傳可指派給 '{0}' 的值,但結束時未回傳值。

描述

#

當傳遞給 Future.catchError 方法的 onError 參數的閉包需要回傳非 null 值(由於 Future 的型別引數),但可能會隱含地回傳 null 時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為傳遞給 catchError 方法的閉包需要回傳 int,但並未以顯式的 return 結束,導致它隱含地回傳 null

dart
void g(Future<int> f) {
  f.catchError((e, st) {});
}

常見修正方式

#

如果閉包有時應該回傳非 null 值,則向閉包添加顯式回傳。

dart
void g(Future<int> f) {
  f.catchError((e, st) {
    return -1;
  });
}

如果閉包應始終回傳 null,則將 Future 的型別引數更改為 voidNull

dart
void g(Future<void> f) {
  f.catchError((e, st) {});
}

函式主體可能正常完成_可為 Null

#

此函數具有可空的回傳型別 '{0}',但結束時未回傳值。

描述

#

當方法或函數可以通過到達末尾而隱含地回傳 null 時,分析器會產生此診斷訊息。雖然這是有效的 Dart 程式碼,但最好明確地回傳 null

範例

#

以下程式碼產生此診斷訊息,因為函數 f 隱含地回傳 null

dart
String? f() {}

常見修正方式

#

如果有意回傳 null,則使其明確。

dart
String? f() {
  return null;
}

如果函數應該沿該路徑回傳非 null 值,則添加遺失的 return 語句。

dart
String? f() {
  return '';
}

switch_成員上的_break_標籤

#

break 標籤解析為 'case' 或 'default' 語句。

描述

#

當 switch 語句內 case 子句中的 break 具有與另一個 case 子句關聯的標籤時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為標籤 l0 的 case 子句關聯。

dart
void f(int i) {
  switch (i) {
    l: case 0:
      break;
    case 1:
      break l;
  }
}

常見修正方式

#

如果目的是將控制權轉移到 switch 之後的語句,則從 break 語句中移除標籤。

dart
void f(int i) {
  switch (i) {
    case 0:
      break;
    case 1:
      break;
  }
}

如果目的是將控制權轉移到不同的 case 區塊,則使用 continue 而不是 break

dart
void f(int i) {
  switch (i) {
    l: case 0:
      break;
    case 1:
      continue l;
  }
}

內建_識別項作為類型

#

內建識別符 '{0}' 不能用作型別。

描述

#

當在預期型別名稱的地方使用內建識別符時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 import 不能用作型別,因為它是一個內建識別符。

dart
import<int> x;

常見修正方式

#

將內建識別符替換為有效型別的名稱。

dart
List<int> x;

宣告中的內建_識別項

#

內建識別符 '{0}' 不能用作前綴名稱。

內建識別符 '{0}' 不能用作型別名稱。

內建識別符 '{0}' 不能用作型別參數名稱。

內建識別符 '{0}' 不能用作 typedef 名稱。

內建識別符 '{0}' 不能用作擴展名稱。

內建識別符 '{0}' 不能用作擴展型別名稱。

描述

#

當類別、擴展、mixin、typedef、型別參數或 import 前綴的宣告中使用的名稱是內建識別符時,分析器會產生此診斷訊息。內建識別符不能用於命名任何這些種類的宣告。

範例

#

以下程式碼產生此診斷訊息,因為 mixin 是一個內建識別符。

dart
extension mixin on int {}

常見修正方式

#

為宣告選擇不同的名稱。

case_區塊未終止

#

'case' 的最後一個語句應為 'break'、'continue'、'rethrow'、'return' 或 'throw'。

描述

#

case 區塊中的最後一個語句不是必需的終止符之一時,分析器會產生此診斷訊息:breakcontinuerethrowreturnthrow

範例

#

以下程式碼產生此診斷訊息,因為 case 區塊以指派結束。

dart
void f(int x) {
  switch (x) {
    case 0:
      x += 2;
    default:
      x += 1;
  }
}

常見修正方式

#

添加必需的終止符之一。

dart
void f(int x) {
  switch (x) {
    case 0:
      x += 2;
      break;
    default:
      x += 1;
  }
}

case_運算式類型實作了_equals

#

switch case 表達式型別 '{0}' 不能覆寫 '==' 運算子。

描述

#

當關鍵字 case 後面的表達式的型別具有 == 運算子的實作,而不是 Object 中的實作時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為關鍵字 case 後面的表達式 (C(0)) 具有型別 C,並且類別 C 覆寫了 == 運算子。

dart
class C {
  final int value;

  const C(this.value);

  bool operator ==(Object other) {
    return false;
  }
}

void f(C c) {
  switch (c) {
    case C(0):
      break;
  }
}

常見修正方式

#

如果沒有強烈的理由不這樣做,則重寫程式碼以使用 if-else 結構。

dart
class C {
  final int value;

  const C(this.value);

  bool operator ==(Object other) {
    return false;
  }
}

void f(C c) {
  if (c == C(0)) {
    // ...
  }
}

如果您無法重寫 switch 語句,並且 == 的實作不是必要的,則將其移除。

dart
class C {
  final int value;

  const C(this.value);
}

void f(C c) {
  switch (c) {
    case C(0):
      break;
  }
}

如果您無法重寫 switch 語句,也無法移除 == 的定義,則找到一些其他可以用於控制 switch 的值。

dart
class C {
  final int value;

  const C(this.value);

  bool operator ==(Object other) {
    return false;
  }
}

void f(C c) {
  switch (c.value) {
    case 0:
      break;
  }
}

case_運算式類型不是_switch_運算式子類型

#

switch case 表達式型別 '{0}' 必須是 switch 表達式型別 '{1}' 的子型別。

描述

#

switch 語句中 case 後面的表達式的靜態型別不是 switch 後面的表達式的靜態型別的子型別時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 1int,它不是 Strings 的型別)的子型別。

dart
void f(String s) {
  switch (s) {
    case 1:
      break;
  }
}

常見修正方式

#

如果 case 表達式的值錯誤,則更改 case 表達式,使其具有所需的型別。

dart
void f(String s) {
  switch (s) {
    case '1':
      break;
  }
}

如果 case 表達式的值正確,則更改 switch 表達式以具有所需的型別。

dart
void f(int s) {
  switch (s) {
    case 1:
      break;
  }
}

從可為 Null 的轉換永遠失敗

#

此轉換始終會拋出例外狀況,因為可空的區域變數 '{0}' 未指派值。

描述

#

當具有可空型別的區域變數尚未指派值,並且被轉換為非可空型別時,分析器會產生此診斷訊息。由於變數尚未指派值,因此它具有預設值 null,導致轉換拋出例外狀況。

範例

#

以下程式碼產生此診斷訊息,因為變數 x 在已知具有值 null 時被轉換為非可空型別 (int)。

dart
void f() {
  num? x;
  x as int;
  print(x);
}

常見修正方式

#

如果預期變數在轉換之前具有值,則添加初始化子或指派。

dart
void f() {
  num? x = 3;
  x as int;
  print(x);
}

如果預期變數不會被指派值,則移除轉換。

dart
void f() {
  num? x;
  print(x);
}

從_null的轉換永遠失敗

#

此轉換始終會拋出例外狀況,因為表達式始終評估為 'null'。

描述

#

當型別為 Null 的表達式被轉換為非可空型別時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為已知 n 始終為 null,但它被轉換為非可空型別。

dart
void f(Null n) {
  n as int;
}

常見修正方式

#

移除不必要的轉換。

dart
void f(Null n) {
  n;
}

轉換為非類型

#

名稱 '{0}' 不是型別,因此不能在 'as' 表達式中使用。

描述

#

當轉換表達式中 as 後面的名稱被定義為型別以外的其他東西時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 x 是一個變數,而不是型別。

dart
num x = 0;
int y = x as x;

常見修正方式

#

將名稱替換為型別的名稱。

dart
num x = 0;
int y = x as int;

類別用作混入

#

類別 '{0}' 不能用作 mixin,因為它既不是 mixin 類別也不是 mixin。

描述

#

當既不是 mixin class 也不是 mixin 的類別在 with 子句中使用時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為類別 M 被用作 mixin,但它未定義為 mixin class

dart
class M {}
class C with M {}

常見修正方式

#

如果類別可以是純 mixin,則將 class 更改為 mixin

dart
mixin M {}
class C with M {}

如果類別需要既是類別又是 mixin,則添加 mixin

dart
mixin class M {}
class C with M {}

來自延遲載入程式庫的集合元素

#

來自延遲載入程式庫的常數值不能用作 'const' map 字面值中的鍵。

來自延遲載入程式庫的常數值不能用作 'const' 建構子中的值。

來自延遲載入程式庫的常數值不能用作 'const' list 字面值中的值。

來自延遲載入程式庫的常數值不能用作 'const' map 字面值中的值。

來自延遲載入程式庫的常數值不能用作 'const' set 字面值中的值。

描述

#

當集合字面值(明確地(因為它以 const 關鍵字作為前綴)或隱含地(因為它出現在 常數上下文 中))包含在使用延遲載入 import 匯入的程式庫中宣告的值時,分析器會產生此診斷訊息。常數在編譯時期評估,而來自延遲載入程式庫的值在編譯時期不可用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

給定一個檔案 a.dart,它定義了常數 zero

dart
const zero = 0;

以下程式碼產生此診斷訊息,因為常數列表字面值包含 a.zero,它是使用 deferred import 匯入的。

dart
import 'a.dart' deferred as a;

var l = const [a.zero];

常見修正方式

#

如果集合字面值不需要是常數,則移除 const 關鍵字。

dart
import 'a.dart' deferred as a;

var l = [a.zero];

如果集合需要是常數,並且必須引用匯入的常數,則從 import 中移除關鍵字 deferred

dart
import 'a.dart' as a;

var l = const [a.zero];

如果您不需要引用常數,則將其替換為合適的值。

dart
var l = const [0];

複合實作了_Finalizable

#

類別 '{0}' 無法實作 Finalizable。

描述

#

StructUnion 的子類別實作 Finalizable 時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為類別 S 實作了 Finalizable

dart
import 'dart:ffi';

final class S extends Struct implements Finalizable {
  external Pointer notEmpty;
}

常見修正方式

#

嘗試從類別中移除 implements 子句。

dart
import 'dart:ffi';

final class S extends Struct {
  external Pointer notEmpty;
}

具體類別具有列舉_超介面

#

具體類別不能將 'Enum' 作為超介面。

描述

#

當具體類別間接地將類別 Enum 作為超介面時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為具體類別 B 由於實作了 A 而將 Enum 作為超介面。

dart
abstract class A implements Enum {}

class B implements A {}

常見修正方式

#

如果實作的類別不是您想要實作的類別,則更改它。

dart
abstract class A implements Enum {}

class B implements C {}

class C {}

如果可以更改實作的類別以不實作 Enum,則執行此操作。

dart
abstract class A {}

class B implements A {}

如果無法更改實作的類別以不實作 Enum,則從 implements 子句中移除它。

dart
abstract class A implements Enum {}

class B {}

具有抽象成員的具體類別

#

'{0}' 必須具有方法主體,因為 '{1}' 不是抽象的。

描述

#

當找到具體類別的成員沒有具體實作時,分析器會產生此診斷訊息。具體類別不允許包含抽象成員。

範例

#

以下程式碼產生此診斷訊息,因為 m 是一個抽象方法,但 C 不是一個抽象類別。

dart
class C {
  void m();
}

常見修正方式

#

如果建立類別的實例是有效的,則為成員提供實作。

dart
class C {
  void m() {}
}

如果建立類別的實例無效,則將類別標記為抽象的。

dart
abstract class C {
  void m();
}

建構子與靜態成員衝突

#

'{0}' 不能用於命名此類別中的建構子和靜態欄位。

'{0}' 不能用於命名此類別中的建構子和靜態 getter。

'{0}' 不能用於命名此類別中的建構子和靜態方法。

'{0}' 不能用於命名此類別中的建構子和靜態 setter。

描述

#

當具名建構子和靜態方法或靜態欄位具有相同的名稱時,分析器會產生此診斷訊息。兩者都使用類別的名稱進行存取,因此具有相同的名稱會使引用不明確。

範例

#

以下程式碼產生此診斷訊息,因為靜態欄位 foo 和具名建構子 foo 具有相同的名稱。

dart
class C {
  C.foo();
  static int foo = 0;
}

以下程式碼產生此診斷訊息,因為靜態方法 foo 和具名建構子 foo 具有相同的名稱。

dart
class C {
  C.foo();
  static void foo() {}
}

常見修正方式

#

重新命名成員或建構子。

泛型介面衝突

#

類別 {0} '{1}' 無法同時實作 '{2}' 和 '{3}',因為型別引數不同。

描述

#

當類別嘗試多次實作泛型介面,並且型別引數的值不相同時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 C 被定義為同時實作 I<int>(因為它擴展了 A)和 I<String>(因為它實作了 B),但 intString 不是相同的型別。

dart
class I<T> {}
class A implements I<int> {}
class B implements I<String> {}
class C extends A implements B {}

常見修正方式

#

重新設計型別層次結構以避免這種情況。例如,您可以將一個或兩個繼承的型別設為泛型,以便 C 可以為兩個型別引數指定相同的型別。

dart
class I<T> {}
class A<S> implements I<S> {}
class B implements I<String> {}
class C extends A<String> implements B {}

類型變數與容器衝突

#

'{0}' 不能用於命名型別參數和定義型別參數的類別。

'{0}' 不能用於命名型別參數和定義型別參數的列舉。

'{0}' 不能用於命名型別參數和定義型別參數的擴展。

'{0}' 不能用於命名型別參數和定義型別參數的擴展型別。

'{0}' 不能用於命名型別參數和定義型別參數的 mixin。

描述

#

當類別、mixin 或擴展宣告宣告的型別參數與宣告它的類別、mixin 或擴展具有相同的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為型別參數 C 與它所屬的類別 C 具有相同的名稱。

dart
class C<C> {}

常見修正方式

#

重新命名型別參數,或類別、mixin 或擴展。

dart
class C<T> {}

類型變數與成員衝突

#

'{0}' 不能用於命名型別參數和此類別中的成員。

'{0}' 不能用於命名型別參數和此列舉中的成員。

'{0}' 不能用於命名型別參數和此擴展型別中的成員。

'{0}' 不能用於命名型別參數和此擴展中的成員。

'{0}' 不能用於命名型別參數和此 mixin 中的成員。

描述

#

當類別、mixin 或擴展宣告宣告的型別參數與宣告它的類別、mixin 或擴展的成員之一具有相同的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為型別參數 T 與欄位 T 具有相同的名稱。

dart
class C<T> {
  int T = 0;
}

常見修正方式

#

重新命名型別參數或與之衝突的成員。

dart
class C<T> {
  int total = 0;
}

常數模式永遠不符合值類型

#

符合的值類型 '{0}' 永遠無法等於類型為 '{1}' 的常數。

描述

#

當常數模式永遠無法與其測試的值相符時,分析器會產生此診斷,因為已知常數的類型永遠不會與值的類型相符。

範例

#

以下程式碼會產生此診斷,因為常數模式 (true) 的類型為 bool,而要比對的值 (x) 的類型為 int,且布林值永遠無法與整數相符。

dart
void f(int x) {
  if (x case true) {}
}

常見修正方式

#

如果值的類型正確,則重新撰寫模式以使其相容

dart
void f(int x) {
  if (x case 3) {}
}

如果常數的類型正確,則重新撰寫值以使其相容

dart
void f(bool x) {
  if (x case true) {}
}

具有非常數運算式的常數模式

#

常數模式的運算式必須是有效的常數。

描述

#

當常數模式具有不是有效常數的運算式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為常數模式 i 不是常數

dart
void f(int e, int i) {
  switch (e) {
    case i:
      break;
  }
}

常見修正方式

#

如果應該比對的值是已知的,則將運算式替換為常數

dart
void f(int e, int i) {
  switch (e) {
    case 0:
      break;
  }
}

如果應該比對的值是未知的,則重新撰寫程式碼以不使用模式

dart
void f(int e, int i) {
  if (e == i) {}
}

const_建構子參數類型不符

#

在常數建構函式中,類型為 '{0}' 的值無法指派給類型為 '{1}' 的參數。

描述

#

當常數值的執行階段類型無法指派給常數建構函式參數的靜態類型時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 i 的執行階段類型為 int,無法指派給 s 的靜態類型

dart
class C {
  final String s;

  const C(this.s);
}

const dynamic i = 0;

void f() {
  const C(i);
}

常見修正方式

#

將正確類型的值傳遞給建構函式

dart
class C {
  final String s;

  const C(this.s);
}

const dynamic i = 0;

void f() {
  const C('$i');
}

由非常數初始化的_const_建構子

#

因為欄位 '{0}' 是以非常數值初始化的,所以無法定義 'const' 建構函式。

描述

#

當建構函式具有關鍵字 const,但類別中的欄位卻初始化為非常數值時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為欄位 s 是以非常數值初始化的

dart
String x = '3';
class C {
  final String s = x;
  const C();
}

常見修正方式

#

如果欄位可以初始化為常數值,則將初始化運算式變更為常數運算式

dart
class C {
  final String s = '3';
  const C();
}

如果欄位無法初始化為常數值,則從建構函式中移除關鍵字 const

dart
String x = '3';
class C {
  final String s = x;
  C();
}

具有非常數_super的_const_建構子

#

常數建構函式無法呼叫 '{0}' 的非常數父類別建構函式。

描述

#

當標記為 const 的建構函式從其父類別叫用未標記為 const 的建構函式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 B 中的 const 建構函式從類別 A 叫用建構函式 nonConst,而父類別建構函式不是 const 建構函式

dart
class A {
  const A();
  A.nonConst();
}

class B extends A {
  const B() : super.nonConst();
}

常見修正方式

#

如果非得要叫用目前正在叫用的父類別建構函式,則從父類別叫用常數建構函式

dart
class A {
  const A();
  A.nonConst();
}

class B extends A {
  const B() : super();
}

如果非得要叫用目前的建構函式,而且您可以修改它,則將 const 新增至父類別中的建構函式

dart
class A {
  const A();
  const A.nonConst();
}

class B extends A {
  const B() : super.nonConst();
}

如果非得要叫用目前的建構函式,而且您無法修改它,則從子類別中的建構函式移除 const

dart
class A {
  const A();
  A.nonConst();
}

class B extends A {
  B() : super.nonConst();
}

具有非_final_欄位的_const_建構子

#

無法為具有非 final 欄位的類別定義常數建構函式。

描述

#

當建構函式標記為常數建構函式,但在具有至少一個非 final 實例欄位(直接或透過繼承)的類別中定義建構函式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為欄位 x 不是 final

dart
class C {
  int x;

  const C(this.x);
}

常見修正方式

#

如果可以將所有欄位標記為 final,請執行此操作

dart
class C {
  final int x;

  const C(this.x);
}

如果無法將所有欄位標記為 final,則從建構函式中移除關鍵字 const

dart
class C {
  int x;

  C(this.x);
}

const_延遲載入類別

#

延遲類別無法以 'const' 建立。

描述

#

當使用延遲匯入匯入的程式庫中的類別用於建立 const 物件時,分析器會產生此診斷。常數會在編譯時期評估,而延遲程式庫中的類別在編譯時期無法使用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

以下程式碼會產生此診斷,因為它嘗試建立延遲程式庫中類別的 const 實例

dart
import 'dart:convert' deferred as convert;

const json2 = convert.JsonCodec();

常見修正方式

#

如果物件不需要是常數,則變更程式碼,使建立非常數實例

dart
import 'dart:convert' deferred as convert;

final json2 = convert.JsonCodec();

如果物件必須是常數,則從匯入指示詞中移除 deferred

dart
import 'dart:convert' as convert;

const json2 = convert.JsonCodec();

使用非常數值初始化的_const

#

常數變數必須以常數值初始化。

描述

#

當將靜態已知不是常數的值指派給宣告為 const 變數的變數時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 x 未宣告為 const

dart
var x = 0;
const y = x;

常見修正方式

#

如果可以將指派的值宣告為 const,則變更宣告

dart
const x = 0;
const y = x;

如果值無法宣告為 const,則從變數中移除 const 修飾詞,可能會改用 final

dart
var x = 0;
final y = x;

來自延遲載入程式庫的非常數值初始化的_const

#

延遲程式庫中的常數值無法用於初始化 'const' 變數。

描述

#

當使用從使用延遲匯入匯入的程式庫中的 const 變數初始化 const 變數時,分析器會產生此診斷。常數會在編譯時期評估,而延遲程式庫中的值在編譯時期無法使用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

以下程式碼會產生此診斷,因為變數 pi 是使用程式庫 dart:math 中的常數 math.pi 初始化的,而 dart:math 是以延遲程式庫匯入的

dart
import 'dart:math' deferred as math;

const pi = math.pi;

常見修正方式

#

如果您需要參考從匯入程式庫中的常數值,則移除關鍵字 deferred

dart
import 'dart:math' as math;

const pi = math.pi;

如果您不需要參考匯入的常數,則移除參考

dart
const pi = 3.14;

const_實例欄位

#

只有靜態欄位可以宣告為 const。

描述

#

當實例欄位標記為 const 時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 f 是實例欄位

dart
class C {
  const int f = 3;
}

常見修正方式

#

如果欄位需要是實例欄位,則移除關鍵字 const,或將其替換為 final

dart
class C {
  final int f = 3;
}

如果欄位確實應該是 const 欄位,則使其成為靜態欄位

dart
class C {
  static const int f = 3;
}

const_map_金鑰不是基本相等性

#

常數 Map 中索引鍵的類型無法覆寫 '==' 運算子或 'hashCode',但類別 '{0}' 卻覆寫了。

描述

#

當用作常數 Map 實值中的索引鍵物件類別實作 == 運算子、 getter hashCode 或兩者時,分析器會產生此診斷。常數 Map 的實作同時使用 == 運算子和 hashCode getter,因此除了從 Object 繼承的實作之外的任何實作,都需要在編譯時期執行任意程式碼,而這是 UnimplementedError。

範例

#

以下程式碼會產生此診斷,因為常數 Map 包含類型為 C 的索引鍵,且類別 C 覆寫了 == 的實作

dart
class C {
  const C();

  bool operator ==(Object other) => true;
}

const map = {C() : 0};

以下程式碼會產生此診斷,因為常數 Map 包含類型為 C 的索引鍵,且類別 C 覆寫了 hashCode 的實作

dart
class C {
  const C();

  int get hashCode => 3;
}

const map = {C() : 0};

常見修正方式

#

如果您可以從類別中移除 ==hashCode 的實作,請執行此操作

dart
class C {
  const C();
}

const map = {C() : 0};

如果您無法從類別中移除 ==hashCode 的實作,則將 Map 設為非常數

dart
class C {
  const C();

  bool operator ==(Object other) => true;
}

final map = {C() : 0};

const_未初始化

#

必須初始化常數 '{0}'。

描述

#

當宣告為常數的變數沒有初始化運算式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 c 未初始化

dart
const c;

常見修正方式

#

新增初始化運算式

dart
const c = 'c';

const_set_元素不是基本相等性

#

(先前稱為 const_set_element_type_implements_equals)

常數 Set 中的元素無法覆寫 '==' 運算子或 'hashCode',但類型 '{0}' 卻覆寫了。

描述

#

當用作常數 Set 實值中的元素物件類別實作 == 運算子、 getter hashCode 或兩者時,分析器會產生此診斷。常數 Set 的實作同時使用 == 運算子和 hashCode getter,因此除了從 Object 繼承的實作之外的任何實作,都需要在編譯時期執行任意程式碼,而這是 UnimplementedError。

範例

#

以下程式碼會產生此診斷,因為常數 Set 包含類型為 C 的元素,且類別 C 覆寫了 == 的實作

dart
class C {
  const C();

  bool operator ==(Object other) => true;
}

const set = {C()};

以下程式碼會產生此診斷,因為常數 Set 包含類型為 C 的元素,且類別 C 覆寫了 hashCode 的實作

dart
class C {
  const C();

  int get hashCode => 3;
}

const map = {C()};

常見修正方式

#

如果您可以從類別中移除 ==hashCode 的實作,請執行此操作

dart
class C {
  const C();
}

const set = {C()};

如果您無法從類別中移除 ==hashCode 的實作,則將 Set 設為非常數

dart
class C {
  const C();

  bool operator ==(Object other) => true;
}

final set = {C()};

const_spread預期是清單或_set

#

在此展開中,預期應為 List 或 Set。

描述

#

當常數 List 或 Set 中展開運算子的運算式評估為 List 或 Set 以外的項目時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 list1 的值為 null,既不是 List 也不是 Set

dart
const dynamic list1 = 42;
const List<int> list2 = [...list1];

常見修正方式

#

將運算式變更為評估為常數 List 或常數 Set 的項目

dart
const dynamic list1 = [42];
const List<int> list2 = [...list1];

const_spread預期是_map

#

在此展開中,預期應為 Map。

描述

#

當常數 Map 中展開運算子的運算式評估為 Map 以外的項目時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 map1 的值為 null,不是 Map

dart
const dynamic map1 = 42;
const Map<String, int> map2 = {...map1};

常見修正方式

#

將運算式變更為評估為常數 Map 的項目

dart
const dynamic map1 = {'answer': 42};
const Map<String, int> map2 = {...map1};

const_搭配非_const

#

正在呼叫的建構函式不是 const 建構函式。

描述

#

當關鍵字 const 用於叫用未標記為 const 的建構函式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 A 中的建構函式不是 const 建構函式

dart
class A {
  A();
}

A f() => const A();

常見修正方式

#

如果想要且有可能使類別成為常數類別(方法是使類別的所有欄位,包括繼承的欄位,都成為 final),則將關鍵字 const 新增至建構函式

dart
class A {
  const A();
}

A f() => const A();

否則,移除關鍵字 const

dart
class A {
  A();
}

A f() => A();

const_搭配非常數引數

#

常數建立的引數必須是常數運算式。

描述

#

當使用非常數運算式的引數叫用 const 建構函式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 i 不是常數

dart
class C {
  final int i;
  const C(this.i);
}
C f(int i) => const C(i);

常見修正方式

#

將所有引數設為常數運算式,或移除 const 關鍵字以使用建構函式的非常數形式

dart
class C {
  final int i;
  const C(this.i);
}
C f(int i) => C(i);

具有類型參數的_const

#

常數建構函式 tear-off 無法使用類型參數作為類型引數。

常數建立無法使用類型參數作為類型引數。

常數函式 tear-off 無法使用類型參數作為類型引數。

描述

#

當類型參數在建構函式的 const 叫用中用作類型引數時,分析器會產生此診斷。不允許這樣做,因為類型參數的值(執行階段將使用的實際類型)在編譯時期無法得知。

範例

#

以下程式碼會產生此診斷,因為建立常數時,類型參數 T 正用作類型引數

dart
class C<T> {
  const C();
}

C<T> newC<T>() => const C<T>();

常見修正方式

#

如果將用於類型參數的類型可以在編譯時期得知,則移除類型參數的使用

dart
class C<T> {
  const C();
}

C<int> newC() => const C<int>();

如果將用於類型參數的類型在執行階段之前無法得知,則移除關鍵字 const

dart
class C<T> {
  const C();
}

C<T> newC<T>() => C<T>();

continue_標籤無效

#

(先前稱為 continue_label_on_switch)

'continue' 陳述式中使用的標籤必須在迴圈或 switch 成員上定義。

描述

#

continue 陳述式中的標籤解析為 switch 陳述式上的標籤時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為用於標記 switch 陳述式的標籤 l 用於 continue 陳述式中

dart
void f(int i) {
  l: switch (i) {
    case 0:
      continue l;
  }
}

常見修正方式

#

尋找達成您所需的控制流程的不同方法;例如,透過引入重新執行 switch 陳述式的迴圈。

struct或_union的建立

#

'Struct' 和 'Union' 的子類別由原生記憶體支援,無法由產生器建構函式具現化。

描述

#

當使用產生器建構函式具現化 StructUnion 的子類別時,分析器會產生此診斷。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷,因為類別 C 是使用產生器建構函式具現化的

dart
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  external int a;
}

void f() {
  C();
}

常見修正方式

#

如果您需要配置類別描述的結構,則使用 ffi 套件來執行此操作

dart
import 'dart:ffi';
import 'package:ffi/ffi.dart';

final class C extends Struct {
  @Int32()
  external int a;
}

void f() {
  final pointer = calloc.allocate<C>(4);
  final c = pointer.ref;
  print(c);
  calloc.free(pointer);
}

使用非類型建立

#

名稱 '{0}' 不是類別。

描述

#

當使用 newconst 的實例建立指定未定義為類別的名稱時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 f 是函式而不是類別

dart
int f() => 0;

void g() {
  new f();
}

常見修正方式

#

如果應建立類別,則將無效名稱替換為有效類別的名稱

dart
int f() => 0;

void g() {
  new Object();
}

如果名稱是函式的名稱,且您想要叫用該函式,則移除 newconst 關鍵字

dart
int f() => 0;

void g() {
  f();
}

無效程式碼

#

無效程式碼。

無效程式碼:已指派給萬用字元變數已標記為 late 且永遠無法參考,因此永遠不會評估此初始化運算式。

描述

#

當找到不會執行的程式碼時,分析器會產生此診斷,因為執行永遠不會到達該程式碼。

範例

#

以下程式碼會產生此診斷,因為 print 的叫用發生在函式傳回之後

dart
void f() {
  return;
  print('here');
}

常見修正方式

#

如果不需要程式碼,則移除它

dart
void f() {
  return;
}

如果需要執行程式碼,則將程式碼移至將會執行的位置

dart
void f() {
  print('here');
  return;
}

或者,重新撰寫之前的程式碼,使其可以到達

dart
void f({bool skipPrinting = true}) {
  if (skipPrinting) {
    return;
  }
  print('here');
}

無效程式碼_catch後面的_catch

#

無效程式碼:在 'catch (e)' 或 'on Object catch (e)' 之後的 Catch 子句永遠不會到達。

描述

#

當找到無法執行的 catch 子句時,分析器會產生此診斷,因為它在 catch (e)on Object catch (e) 形式的 catch 子句之後。將選取與擲回物件相符的第一個 catch 子句,而這兩種形式都會與任何物件相符,因此不會選取它們之後的任何 catch 子句。

範例

#

下列程式碼會產生此診斷訊息

dart
void f() {
  try {
  } catch (e) {
  } on String {
  }
}

常見修正方式

#

如果子句應該是可選取的,則將子句移至一般子句之前

dart
void f() {
  try {
  } on String {
  } catch (e) {
  }
}

如果子句不需要是可選取的,則移除它

dart
void f() {
  try {
  } catch (e) {
  }
}

無效程式碼_on_catch_子類型

#

無效程式碼:此 on-catch 區塊將不會執行,因為 '{0}' 是 '{1}' 的子類型,因此已在先前捕捉到。

描述

#

當找到無法執行的 catch 子句時,分析器會產生此診斷,因為它在捕捉相同類型或子句類型之父類型的 catch 子句之後。將選取與擲回物件相符的第一個 catch 子句,而先前的子句永遠與醒目提示子句可比對的任何項目相符,因此永遠不會選取醒目提示的子句。

範例

#

下列程式碼會產生此診斷訊息

dart
void f() {
  try {
  } on num {
  } on int {
  }
}

常見修正方式

#

如果子句應該是可選取的,則將子句移至一般子句之前

dart
void f() {
  try {
  } on int {
  } on num {
  }
}

如果子句不需要是可選取的,則移除它

dart
void f() {
  try {
  } on num {
  }
}

無效_null_感知_運算式

#

左運算元不可為 null,因此永遠不會執行右運算元。

描述

#

分析器在兩種情況下會產生此診斷。

第一種情況是當 ?? 運算子的左運算元不可為 null 時。只有在左運算元的值為 null 時,才會評估右運算元,而且因為左運算元不可為 null,因此永遠不會評估右運算元。

第二種情況是當使用 ??= 運算子的指派左側不可為 null 時。只有在左側的值為 null 時,才會評估右側,而且因為左側不可為 null,因此永遠不會評估右側。

範例

#

以下程式碼會產生此診斷,因為 x 不可為 null

dart
int f(int x) {
  return x ?? 0;
}

以下程式碼會產生此診斷,因為 f 不可為 null

dart
class C {
  int f = -1;

  void m(int x) {
    f ??= x;
  }
}

常見修正方式

#

如果針對 ?? 運算子報告診斷,則移除 ?? 運算子和右運算元

dart
int f(int x) {
  return x;
}

如果針對指派報告診斷,且不需要指派,則移除指派

dart
class C {
  int f = -1;

  void m(int x) {
  }
}

如果需要指派,但應根據不同的條件,則重新撰寫程式碼以使用 = 和不同的條件

dart
class C {
  int f = -1;

  void m(int x) {
    if (f < 0) {
      f = x;
    }
  }
}

預設清單建構子

#

當啟用 Null 安全性時,預設的 'List' 建構函式無法使用。

描述

#

當分析器在已選擇加入 Null 安全性的程式碼中找到類別 List 的預設建構函式的使用時,會產生此診斷。

範例

#

假設以下程式碼已選擇加入 Null 安全性,它會產生此診斷,因為它使用預設的 List 建構函式

dart
var l = List<int>();

常見修正方式

#

如果未提供初始大小,則轉換程式碼以使用 List 實值

dart
var l = <int>[];

如果需要提供初始大小,且元素的單一合理初始值,則使用 List.filled

dart
var l = List.filled(3, 0);

如果需要提供初始大小,但每個元素都需要計算,則使用 List.generate

dart
var l = List.generate(3, (i) => i);

函式類型中的預設值

#

函式類型中的參數不能有預設值。

描述

#

當與參數相關聯的函式類型包含具有預設值的選用參數時,分析器會產生此診斷。不允許這樣做,因為參數的預設值不是函式類型的一部分,因此包含它們不會提供任何值。

範例

#

以下程式碼會產生此診斷,因為參數 p 具有預設值,即使它是參數 g 類型的一部分

dart
void f(void Function([int p = 0]) g) {
}

常見修正方式

#

從函式類型的參數中移除預設值

dart
void f(void Function([int p]) g) {
}

重新導向_factory_建構子中的預設值

#

重新導向至另一個建構函式的 Factory 建構函式中不允許預設值。

描述

#

當重新導向至另一個建構函式的 Factory 建構函式為選用參數指定預設值時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 A 中的 Factory 建構函式具有選用參數 x 的預設值

dart
class A {
  factory A([int x = 0]) = B;
}

class B implements A {
  B([int x = 1]) {}
}

常見修正方式

#

從 Factory 建構函式中移除預設值

dart
class A {
  factory A([int x]) = B;
}

class B implements A {
  B([int x = 1]) {}
}

請注意,此修正可能會變更省略選用參數時使用的值。如果發生這種情況,而且該變更是問題,則考慮使選用參數成為 Factory 方法中的必要參數

dart
class A {
 factory A(int x) = B;
}

class B implements A {
  B([int x = 1]) {}
}

必要參數的預設值

#

必要的具名參數不能有預設值。

描述

#

當具名參數同時具有 required 修飾詞和預設值時,分析器會產生此診斷。如果參數是必要的,則在呼叫站點始終會提供參數的值,因此永遠不會使用預設值。

範例

#

以下程式碼會產生此診斷

dart
void log({required String message = 'no message'}) {}

常見修正方式

#

如果參數確實是必要的,則移除預設值

dart
void log({required String message}) {}

如果參數並非始終必要,則移除 required 修飾詞

dart
void log({String message = 'no message'}) {}

擴充功能的延遲載入匯入

#

延遲程式庫的匯入必須隱藏所有擴充功能。

描述

#

當使用延遲匯入匯入的程式庫宣告在匯入程式庫中可見的擴充功能時,分析器會產生此診斷。擴充功能方法會在編譯時期解析,而延遲程式庫中的擴充功能在編譯時期無法使用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

假設檔案 a.dart 定義具名擴充功能

dart
class C {}

extension E on String {
  int get size => length;
}

以下程式碼會產生此診斷,因為具名擴充功能對程式庫可見

dart
import 'a.dart' deferred as a;

void f() {
  a.C();
}

常見修正方式

#

如果程式庫必須匯入為 deferred,則新增 show 子句列出正在參考的名稱,或新增 hide 子句列出所有具名擴充功能。新增 show 子句看起來會像這樣

dart
import 'a.dart' deferred as a show C;

void f() {
  a.C();
}

新增 hide 子句看起來會像這樣

dart
import 'a.dart' deferred as a hide E;

void f() {
  a.C();
}

使用第一個修正的好處是,如果將新擴充功能新增至匯入的程式庫,則擴充功能不會導致產生診斷。

如果程式庫不需要匯入為 deferred,或者如果您需要使用其中宣告的擴充功能方法,則移除關鍵字 deferred

dart
import 'a.dart' as a;

void f() {
  a.C();
}

明確未賦值的_late_區域變數

#

在此點,late 區域變數 '{0}' 明確未指派。

描述

#

明確指派 分析顯示標記為 late 的區域變數在指派之前讀取時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 x 在讀取之前未指派值

dart
void f(bool b) {
  late int x;
  print(x);
}

常見修正方式

#

在從變數讀取之前,將值指派給變數

dart
void f(bool b) {
  late int x;
  x = b ? 1 : 0;
  print(x);
}

相依性欄位不是_map

#

欄位 '{0}' 的值應為 Map。

描述

#

dependenciesdev_dependencies 索引鍵的值不是 Map 時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為最上層 dependencies 索引鍵的值是 List

yaml
name: example
dependencies:
  - meta

常見修正方式

#

使用 Map 作為 dependencies 索引鍵的值

yaml
name: example
dependencies:
  meta: ^1.0.2

已淘汰的冒號作為預設值

#

在預設值之前使用冒號作為分隔符號已過時,且在語言版本 3.0 及更高版本中將不再支援。

描述

#

當冒號 (:) 用作選用具名參數的預設值之前的分隔符號時,分析器會產生此診斷。雖然允許使用此語法,但建議改用等號 (=)。

範例

#

以下程式碼會產生此診斷,因為在選用參數 i 的預設值之前使用了冒號

dart
void f({int i : 0}) {}

常見修正方式

#

將冒號替換為等號。

dart
void f({int i = 0}) {}

已淘汰的匯出使用

#

間接匯入 '{0}' 的能力已過時。

描述

#

當一個程式庫從第二個程式庫匯入名稱,且第二個程式庫從第三個程式庫匯出名稱,但已指出未來不會匯出第三個程式庫時,分析器會產生此診斷。

範例

#

假設程式庫 a.dart 定義類別 A

dart
class A {}

以及第二個程式庫 b.dart 匯出 a.dart,但已將匯出標記為已過時

dart
import 'a.dart';

@deprecated
export 'a.dart';

以下程式碼會產生此診斷,因為類別 A 在未來的某些版本中不會從 b.dart 匯出

dart
import 'b.dart';

A? a;

常見修正方式

#

如果名稱可從您可以匯入的不同程式庫取得,則將現有的匯入替換為該程式庫的匯入(如果您仍然需要舊的匯入,則新增定義程式庫的匯入)

dart
import 'a.dart';

A? a;

如果名稱不可用,則尋找程式庫作者的指示或直接聯絡他們,以瞭解如何更新您的程式碼。

已淘汰的欄位

#

欄位 '{0}' 已不再使用,可以移除。

描述

#

當在 pubspec.yaml 檔案中使用已過時的索引鍵時,分析器會產生此診斷。未使用的索引鍵會佔用空間,且可能暗示不再有效的語意。

範例

#

以下程式碼會產生此診斷,因為 author 索引鍵已不再使用

dart
name: example
author: 'Dash'

常見修正方式

#

移除已過時的索引鍵

dart
name: example

已淘汰的成員使用

#

'{0}' 已過時,不應使用。

'{0}' 已過時,不應使用。{1}

描述

#

當已過時的程式庫或類別成員在不同的套件中使用時,分析器會產生此診斷。

範例

#

如果類別 C 中的方法 m@deprecated 註解,則以下程式碼會產生此診斷

dart
void f(C c) {
  c.m();
}

常見修正方式

#

使用 @deprecated 註解之宣告的文件應指出要使用哪些程式碼來取代已過時的程式碼。

來自相同套件的已淘汰成員使用

#

'{0}' 已過時,不應使用。

'{0}' 已過時,不應使用。{1}

描述

#

當已過時的程式庫成員或類別成員在宣告它的同一個套件中使用時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 x 已過時

dart
@deprecated
var x = 0;
var y = x;

常見修正方式

#

修正取決於已過時的內容以及取代項目。已過時宣告的文件應指出要使用哪些程式碼來取代已過時的程式碼。

註解參考中已淘汰的_new

#

在註解參考中使用 'new' 關鍵字已過時。

描述

#

當註解參考(文件註解中以方括號括住的宣告名稱)使用關鍵字 new 來參考建構函式時,分析器會產生此診斷。此形式已過時。

範例

#

以下程式碼會產生此診斷,因為未命名的建構函式正使用 new C 參考

dart
/// See [new C].
class C {
  C();
}

以下程式碼會產生此診斷,因為具名建構函式 c 正使用 new C.c 參考

dart
/// See [new C.c].
class C {
  C.c();
}

常見修正方式

#

如果您要參考具名建構函式,則移除關鍵字 new

dart
/// See [C.c].
class C {
  C.c();
}

如果您要參考未命名的建構函式,則移除關鍵字 new,並在類別名稱後附加 .new

dart
/// See [C.new].
class C {
  C.c();
}

函式已淘汰的子類型

#

擴充 'Function' 已過時。

實作 'Function' 無效。

混入 'Function' 已過時。

描述

#

當類別 Function 用於類別或 Mixin 的 extendsimplementswith 子句中時,分析器會產生此診斷。以這種方式使用類別 Function 沒有語意值,因此實際上是無效程式碼。

範例

#

以下程式碼會產生此診斷,因為 Function 用作 F 的父類別

dart
class F extends Function {}

常見修正方式

#

從它所在的任何子句中移除類別 Function,如果 Function 是子句中唯一的類型,則移除整個子句

dart
class F {}

不允許的類型具現化運算式

#

只有泛型類型、泛型函式、泛型實例方法或泛型建構函式可以有類型引數。

描述

#

當具有任何非允許值種類之一的值的運算式後接類型引數時,分析器會產生此診斷。允許的值種類為

  • 泛型類型,
  • 泛型建構函式,以及
  • 泛型函式,包括最上層函式、靜態和實例成員以及區域函式。

範例

#

以下程式碼會產生此診斷,因為 i 是最上層變數,不是允許的情況之一

dart
int i = 1;

void f() {
  print(i<int>);
}

常見修正方式

#

如果參考的值正確,則移除類型引數

dart
int i = 1;

void f() {
  print(i);
}

除法最佳化

#

運算子 x ~/ y 比 (x / y).toInt() 更有效率。

描述

#

當除以兩個數字的結果使用 toInt 轉換為整數時,分析器會產生此診斷。Dart 具有內建的整數除法運算子,既更有效率又更簡潔。

範例

#

以下程式碼會產生此診斷,因為除以 xy 的結果使用 toInt 轉換為整數

dart
int divide(int x, int y) => (x / y).toInt();

常見修正方式

#

使用整數除法運算子 (~/)

dart
int divide(int x, int y) => x ~/ y;

重複的建構子

#

已定義名稱為 '{0}' 的建構函式。

已定義未命名的建構函式。

描述

#

當類別宣告多個未命名的建構函式,或宣告多個具有相同名稱的建構函式時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為未命名的建構函式有兩個宣告

dart
class C {
  C();

  C();
}

以下程式碼會產生此診斷,因為名稱為 m 的建構函式有兩個宣告

dart
class C {
  C.m();

  C.m();
}

常見修正方式

#

如果有多個未命名的建構函式,且需要所有建構函式,則為它們全部或除其中一個之外的所有建構函式命名

dart
class C {
  C();

  C.n();
}

如果有多個未命名的建構函式,且除了其中一個之外的所有建構函式都是不需要的,則移除不需要的建構函式

dart
class C {
  C();
}

如果有多個具名建構式,且所有建構式都是必要的,則重新命名除了其中一個以外的所有建構式

dart
class C {
  C.m();

  C.n();
}

如果有多個具名建構式,且除了其中一個以外的所有建構式都是不必要的,則移除不必要的建構式

dart
class C {
  C.m();
}

重複的定義

#

名稱「{0}」已定義。

描述

#

當宣告名稱時,且在相同範圍中存在先前宣告的同名名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 x 被宣告了兩次

dart
int x = 0;
int x = 1;

常見修正方式

#

為其中一個宣告選擇不同的名稱。

dart
int x = 0;
int y = 1;

重複的匯出

#

重複匯出。

描述

#

當找到與檔案中先前的匯出指令相同的匯出指令時,分析器會產生此診斷訊息。第二個匯出指令沒有增加任何價值,應該移除。

範例

#

以下程式碼會產生此診斷訊息,因為相同的程式庫被匯出了兩次

dart
export 'package:meta/meta.dart';
export 'package:meta/meta.dart';

常見修正方式

#

移除不必要的匯出

dart
export 'package:meta/meta.dart';

重複的欄位形式參數

#

欄位「{0}」無法在同一個建構式中由多個參數初始化。

描述

#

當建構式的參數列表中,同一個欄位有多個初始化形式參數時,分析器會產生此診斷訊息。指派一個會立即被覆寫的值是沒有意義的。

範例

#

以下程式碼會產生此診斷訊息,因為 this.f 在參數列表中出現了兩次

dart
class C {
  int f;

  C(this.f, this.f) {}
}

常見修正方式

#

移除其中一個初始化形式參數

dart
class C {
  int f;

  C(this.f) {}
}

重複的欄位名稱

#

欄位名稱「{0}」已在此記錄中使用。

描述

#

當記錄字面量或記錄類型註釋包含一個欄位,其名稱與同一個字面量或類型中先前宣告的欄位名稱相同時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為記錄字面量有兩個名為 a 的欄位

dart
var r = (a: 1, a: 2);

以下程式碼會產生此診斷訊息,因為記錄類型註釋有兩個名為 a 的欄位,一個是位置欄位,另一個是具名欄位

dart
void f((int a, {int a}) r) {}

常見修正方式

#

重新命名其中一個或兩個欄位

dart
var r = (a: 1, b: 2);

重複的隱藏名稱

#

重複隱藏名稱。

描述

#

當一個名稱在 hide 子句中多次出現時,分析器會產生此診斷訊息。重複名稱是不必要的。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 min 被隱藏了不只一次

dart
import 'dart:math' hide min, min;

var x = pi;

常見修正方式

#

如果名稱在一個或多個地方被錯誤輸入,則更正錯誤輸入的名稱

dart
import 'dart:math' hide max, min;

var x = pi;

如果名稱沒有被錯誤輸入,則從列表中移除不必要的名稱

dart
import 'dart:math' hide min;

var x = pi;

重複的_ignore

#

診斷訊息「{0}」在此處不需要被忽略,因為它已經被忽略了。

描述

#

當診斷訊息名稱出現在 ignore 註解中,但該診斷訊息已經被忽略時,分析器會產生此診斷訊息,可能是因為它已經包含在同一個 ignore 註解中,或是因為它出現在 ignore-in-file 註解中。

範例

#

以下程式碼會產生此診斷訊息,因為名為 unused_local_variable 的診斷訊息已經被整個檔案忽略,因此不需要在特定行上忽略它

dart
// ignore_for_file: unused_local_variable
void f() {
  // ignore: unused_local_variable
  var x = 0;
}

以下程式碼會產生此診斷訊息,因為名為 unused_local_variable 的診斷訊息在同一行被忽略了兩次

dart
void f() {
  // ignore: unused_local_variable, unused_local_variable
  var x = 0;
}

常見修正方式

#

移除忽略註解,或者如果忽略註解忽略了多個診斷訊息,則移除不必要的診斷訊息名稱

dart
// ignore_for_file: unused_local_variable
void f() {
  var x = 0;
}

重複的匯入

#

重複匯入。

描述

#

當找到與檔案中先前的匯入指令相同的匯入指令時,分析器會產生此診斷訊息。第二個匯入指令沒有增加任何價值,應該移除。

範例

#

下列程式碼會產生此診斷訊息

dart
import 'package:meta/meta.dart';
import 'package:meta/meta.dart';

@sealed class C {}

常見修正方式

#

移除不必要的匯入

dart
import 'package:meta/meta.dart';

@sealed class C {}

重複的具名引數

#

具名參數「{0}」的引數已經指定過了。

描述

#

當調用具有兩個或多個同名具名引數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為有兩個名稱為 a 的引數

dart
void f(C c) {
  c.m(a: 0, a: 1);
}

class C {
  void m({int? a, int? b}) {}
}

常見修正方式

#

如果其中一個引數應該有不同的名稱,則更改名稱

dart
void f(C c) {
  c.m(a: 0, b: 1);
}

class C {
  void m({int? a, int? b}) {}
}

如果其中一個引數是錯誤的,則移除它

dart
void f(C c) {
  c.m(a: 1);
}

class C {
  void m({int? a, int? b}) {}
}

重複的_part

#

程式庫已經包含一個 URI 為「{0}」的部分。

描述

#

當單一檔案在多個 part 指令中被引用時,分析器會產生此診斷訊息。

範例

#

給定一個包含以下內容的檔案 part.dart

dart
part of 'test.dart';

以下程式碼會產生此診斷訊息,因為檔案 part.dart 被包含了多次

dart
part 'part.dart';
part 'part.dart';

常見修正方式

#

移除除了第一個以外的所有重複 part 指令

dart
part 'part.dart';

模式賦值變數重複

#

變數「{0}」已在此模式中被賦值。

描述

#

當單一模式變數在同一個模式賦值中被賦值多次時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為變數 a 在模式 (a, a) 中被賦值了兩次

dart
int f((int, int) r) {
  int a;
  (a, a) = r;
  return a;
}

常見修正方式

#

如果您需要捕獲所有值,則為每個要匹配的子模式使用唯一的變數

dart
int f((int, int) r) {
  int a, b;
  (a, b) = r;
  return a + b;
}

如果某些值不需要被捕獲,則使用萬用字元模式 _ 以避免必須將值綁定到變數

dart
int f((int, int) r) {
  int a;
  (_, a) = r;
  return a;
}

模式欄位重複

#

欄位「{0}」已在此模式中被匹配。

描述

#

當記錄模式多次匹配同一個欄位,或者當物件模式多次匹配同一個 getter 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為記錄欄位 a 在同一個記錄模式中被匹配了兩次

dart
void f(({int a, int b}) r) {
  switch (r) {
    case (a: 1, a: 2):
      return;
  }
}

以下程式碼會產生此診斷訊息,因為 getter f 在同一個物件模式中被匹配了兩次

dart
void f(Object o) {
  switch (o) {
    case C(f: 1, f: 2):
      return;
  }
}
class C {
  int? f;
}

常見修正方式

#

如果模式應該匹配重複欄位的多個值,則使用邏輯或模式

dart
void f(({int a, int b}) r) {
  switch (r) {
    case (a: 1, b: _) || (a: 2, b: _):
      break;
  }
}

如果模式應該匹配多個欄位,則更改其中一個欄位的名稱

dart
void f(({int a, int b}) r) {
  switch (r) {
    case (a: 1, b: 2):
      return;
  }
}

模式中重複的其餘元素

#

在列表或 Map 模式中,最多允許一個 rest 元素。

描述

#

當列表或 Map 模式中存在多個 rest 模式時,分析器會產生此診斷訊息。rest 模式將捕獲任何未被其他子模式匹配的值,這使得後續的 rest 模式變得不必要,因為沒有剩餘任何東西可以捕獲。

範例

#

以下程式碼會產生此診斷訊息,因為列表模式中有兩個 rest 模式

dart
void f(List<int> x) {
  if (x case [0, ..., ...]) {}
}

常見修正方式

#

移除除了其中一個以外的所有 rest 模式

dart
void f(List<int> x) {
  if (x case [0, ...]) {}
}

重複的顯示名稱

#

重複顯示名稱。

描述

#

當一個名稱在 show 子句中多次出現時,分析器會產生此診斷訊息。重複名稱是不必要的。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 min 被顯示了不只一次

dart
import 'dart:math' show min, min;

var x = min(2, min(0, 1));

常見修正方式

#

如果名稱在一個或多個地方被錯誤輸入,則更正錯誤輸入的名稱

dart
import 'dart:math' show max, min;

var x = max(2, min(0, 1));

如果名稱沒有被錯誤輸入,則從列表中移除不必要的名稱

dart
import 'dart:math' show min;

var x = min(2, min(0, 1));

重複的變數模式

#

變數「{0}」已在此模式中定義。

描述

#

當邏輯 AND 模式的分支宣告了一個變數,該變數已在同一個模式的較早分支中宣告時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為變數 a 在邏輯 AND 模式的兩個分支中都被宣告了

dart
void f((int, int) r) {
  if (r case (var a, 0) && (0, var a)) {
    print(a);
  }
}

常見修正方式

#

如果您需要在多個分支中捕獲匹配的值,則更改變數的名稱,使其成為唯一的

dart
void f((int, int) r) {
  if (r case (var a, 0) && (0, var b)) {
    print(a + b);
  }
}

如果您只需要在一個分支上捕獲匹配的值,則從除了其中一個分支以外的所有分支中移除變數模式

dart
void f((int, int) r) {
  if (r case (var a, 0) && (0, _)) {
    print(a);
  }
}

空的_map_模式

#

Map 模式必須至少有一個條目。

描述

#

當 Map 模式為空時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 Map 模式為空

dart
void f(Map<int, String> x) {
  if (x case {}) {}
}

常見修正方式

#

如果模式應該匹配任何 Map,則將其替換為物件模式

dart
void f(Map<int, String> x) {
  if (x case Map()) {}
}

如果模式應該僅匹配空 Map,則檢查模式中的長度

dart
void f(Map<int, String> x) {
  if (x case Map(isEmpty: true)) {}
}

具有逗號的空記錄字面值

#

沒有欄位的記錄字面量不能有尾隨逗號。

描述

#

當沒有欄位的記錄字面量具有尾隨逗號時,分析器會產生此診斷訊息。空的記錄字面量不能包含逗號。

範例

#

以下程式碼會產生此診斷訊息,因為空的記錄字面量具有尾隨逗號

dart
var r = (,);

常見修正方式

#

如果記錄旨在為空,則移除逗號

dart
var r = ();

如果記錄旨在具有一個或多個欄位,則新增用於計算這些欄位值的表達式

dart
var r = (3, 4);

空的記錄類型具名欄位清單

#

記錄類型中具名欄位的列表不能為空。

描述

#

當記錄類型具有空的具名欄位列表時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為記錄類型具有空的具名欄位列表

dart
void f((int, int, {}) r) {}

常見修正方式

#

如果記錄旨在具有具名欄位,則新增欄位的類型和名稱

dart
void f((int, int, {int z}) r) {}

如果記錄不旨在具有具名欄位,則移除大括號

dart
void f((int, int) r) {}

具有逗號的空記錄類型

#

沒有欄位的記錄類型不能有尾隨逗號。

描述

#

當沒有欄位的記錄類型具有尾隨逗號時,分析器會產生此診斷訊息。空的記錄類型不能包含逗號。

範例

#

以下程式碼會產生此診斷訊息,因為空的記錄類型具有尾隨逗號

dart
void f((,) r) {}

常見修正方式

#

如果記錄類型旨在為空,則移除逗號

dart
void f(() r) {}

如果記錄類型旨在具有一個或多個欄位,則新增這些欄位的類型

dart
void f((int, int) r) {}

空的_struct

#

類別「{0}」不能為空,因為它是「{1}」的子類別。

描述

#

StructUnion 的子類別沒有任何欄位時,分析器會產生此診斷訊息。不支援空的 StructUnion

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為擴展 Struct 的類別 C 沒有宣告任何欄位

dart
import 'dart:ffi';

final class C extends Struct {}

常見修正方式

#

如果類別旨在作為結構體,則宣告一個或多個欄位

dart
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  external int x;
}

如果類別旨在用作 Pointer 的類型引數,則使其成為 Opaque 的子類別

dart
import 'dart:ffi';

final class C extends Opaque {}

如果類別不旨在作為結構體,則移除或更改 extends 子句

dart
class C {}

列舉常數與封閉項名稱相同

#

列舉值的名稱不能與列舉的名稱相同。

描述

#

當列舉值與宣告它的列舉具有相同的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列舉值 E 與封閉列舉 E 具有相同的名稱

dart
enum E {
  E
}

常見修正方式

#

如果列舉的名稱是正確的,則重新命名常數

dart
enum E {
  e
}

如果常數的名稱是正確的,則重新命名列舉

dart
enum F {
  E
}

具有非常數建構子的列舉常數

#

調用的建構式不是「const」建構式。

描述

#

當使用工廠建構式或未標記為 const 的產生器建構式建立列舉值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列舉值 e 正在由工廠建構式初始化

dart
enum E {
  e();

  factory E() => e;
}

常見修正方式

#

使用標記為 const 的產生器建構式

dart
enum E {
  e._();

  factory E() => e;

  const E._();
}

具有實例變數的列舉混入

#

應用於列舉的 Mixin 不能具有實例變數。

描述

#

當應用於列舉的 Mixin 宣告了一個或多個實例變數時,分析器會產生此診斷訊息。這是不允許的,因為列舉值是常數,並且列舉中的建構式無法初始化任何 Mixin 的欄位。

範例

#

以下程式碼會產生此診斷訊息,因為 Mixin M 定義了實例欄位 x

dart
mixin M {
  int x = 0;
}

enum E with M {
  a
}

常見修正方式

#

如果您需要應用 Mixin,則將所有實例欄位更改為 getter 和 setter 對,並在必要時在列舉中實現它們

dart
mixin M {
  int get x => 0;
}

enum E with M {
  a
}

如果您不需要應用 Mixin,則移除它

dart
enum E {
  a
}

具有抽象成員的列舉

#

「{0}」必須具有方法主體,因為「{1}」是一個列舉。

描述

#

當找到列舉的成員沒有具體實現時,分析器會產生此診斷訊息。列舉不允許包含抽象成員。

範例

#

以下程式碼會產生此診斷訊息,因為 m 是一個抽象方法,而 E 是一個列舉

dart
enum E {
  e;

  void m();
}

常見修正方式

#

為成員提供一個實現

dart
enum E {
  e;

  void m() {}
}

具有名稱值的列舉

#

名稱 'values' 不是列舉的有效名稱。

描述

#

當列舉被宣告為具有名稱 values 時,分析器會產生此診斷訊息。這是不允許的,因為列舉具有隱含的靜態欄位,名為 values,而兩者會衝突。

範例

#

以下程式碼會產生此診斷訊息,因為有一個列舉宣告具有名稱 values

dart
enum values {
  c
}

常見修正方式

#

將列舉重新命名為 values 以外的名稱。

const_set中相等的元素

#

常數 Set 字面量中的兩個元素不能相等。

描述

#

當常數 Set 字面量中的兩個元素具有相同的值時,分析器會產生此診斷訊息。Set 只能包含每個值一次,這表示其中一個值是不必要的。

範例

#

以下程式碼會產生此診斷訊息,因為字串 'a' 被指定了兩次

dart
const Set<String> set = {'a', 'a'};

常見修正方式

#

移除其中一個重複的值

dart
const Set<String> set = {'a'};

請注意,字面量 Set 保留其元素的順序,因此選擇移除哪個元素可能會影響迭代器返回元素的順序。

set中相等的元素

#

Set 字面量中的兩個元素不應該相等。

描述

#

當非常數 Set 中的元素與同一個 Set 中的先前元素相同時,分析器會產生此診斷訊息。如果兩個元素相同,則第二個值會被忽略,這使得同時擁有這兩個元素變得毫無意義,並且可能表示一個錯誤。

範例

#

以下程式碼會產生此診斷訊息,因為元素 1 出現了兩次

dart
const a = 1;
const b = 1;
var s = <int>{a, b};

常見修正方式

#

如果兩個元素都應該包含在 Set 中,則更改其中一個元素

dart
const a = 1;
const b = 2;
var s = <int>{a, b};

如果只需要其中一個元素,則移除不需要的那個

dart
const a = 1;
var s = <int>{a};

請注意,字面量 Set 保留其元素的順序,因此選擇移除哪個元素可能會影響迭代器返回元素的順序。

const_map中相等的金鑰

#

常數 Map 字面量中的兩個鍵不能相等。

描述

#

當常數 Map 中的鍵與同一個 Map 中的先前鍵相同時,分析器會產生此診斷訊息。如果兩個鍵相同,則第二個值會覆寫第一個值,這使得同時擁有這兩個鍵值對變得毫無意義。

範例

#

以下程式碼會產生此診斷訊息,因為鍵 1 被使用了兩次

dart
const map = <int, String>{1: 'a', 2: 'b', 1: 'c', 4: 'd'};

常見修正方式

#

如果兩個條目都應該包含在 Map 中,則更改其中一個鍵使其不同

dart
const map = <int, String>{1: 'a', 2: 'b', 3: 'c', 4: 'd'};

如果只需要其中一個條目,則移除不需要的那個

dart
const map = <int, String>{1: 'a', 2: 'b', 4: 'd'};

請注意,字面量 Map 保留其條目的順序,因此選擇移除哪個條目可能會影響迭代器返回鍵和值的順序。

map中相等的金鑰

#

Map 字面量中的兩個鍵不應該相等。

描述

#

當非常數 Map 中的鍵與同一個 Map 中的先前鍵相同時,分析器會產生此診斷訊息。如果兩個鍵相同,則第二個值會覆寫第一個值,這使得同時擁有這兩個鍵值對變得毫無意義,並且可能表示一個錯誤。

範例

#

以下程式碼會產生此診斷訊息,因為鍵 ab 具有相同的值

dart
const a = 1;
const b = 1;
var m = <int, String>{a: 'a', b: 'b'};

常見修正方式

#

如果兩個條目都應該包含在 Map 中,則更改其中一個鍵

dart
const a = 1;
const b = 2;
var m = <int, String>{a: 'a', b: 'b'};

如果只需要其中一個條目,則移除不需要的那個

dart
const a = 1;
var m = <int, String>{a: 'a'};

請注意,字面量 Map 保留其條目的順序,因此選擇移除哪個條目可能會影響迭代器返回鍵和值的順序。

map_模式中相等的金鑰

#

Map 模式中的兩個鍵不能相等。

描述

#

當 Map 模式包含多個具有相同名稱的鍵時,分析器會產生此診斷訊息。同一個鍵不能被匹配兩次。

範例

#

以下程式碼會產生此診斷訊息,因為鍵 'a' 出現了兩次

dart
void f(Map<String, int> x) {
  if (x case {'a': 1, 'a': 2}) {}
}

常見修正方式

#

如果您嘗試匹配兩個不同的鍵,則更改模式中的其中一個鍵

dart
void f(Map<String, int> x) {
  if (x case {'a': 1, 'b': 2}) {}
}

如果您嘗試匹配同一個鍵,但允許匹配多個模式中的任何一個,則使用邏輯或模式

dart
void f(Map<String, int> x) {
  if (x case {'a': 1 || 2}) {}
}

預期一個清單模式類型引數

#

列表模式需要一個或零個類型引數,但找到了 {0} 個。

描述

#

當列表模式具有多個類型引數時,分析器會產生此診斷訊息。列表模式可以具有零個或一個類型引數,但不能有多個。

範例

#

以下程式碼會產生此診斷訊息,因為列表模式 ([0]) 具有兩個類型引數

dart
void f(Object x) {
  if (x case <int, int>[0]) {}
}

常見修正方式

#

移除除了其中一個以外的所有類型引數

dart
void f(Object x) {
  if (x case <int>[0]) {}
}

預期一個清單類型引數

#

列表字面量需要一個或零個類型引數,但找到了 {0} 個。

描述

#

當列表字面量具有多個類型引數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列表字面量具有兩個類型引數,但它最多只能有一個

dart
var l = <int, int>[];

常見修正方式

#

移除除了其中一個以外的所有類型引數

dart
var l = <int>[];

預期一個_set類型引數

#

Set 字面量需要一個或零個類型引數,但找到了 {0} 個。

描述

#

當 Set 字面量具有多個類型引數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 Set 字面量具有三個類型引數,但它最多只能有一個

dart
var s = <int, String, int>{0, 'a', 1};

常見修正方式

#

移除除了其中一個以外的所有類型引數

dart
var s = <int>{0, 1};

預期兩個_map_模式類型引數

#

Map 模式需要兩個或零個類型引數,但找到了 {0} 個。

描述

#

當 Map 模式具有一個類型引數或多於兩個類型引數時,分析器會產生此診斷訊息。Map 模式可以具有兩個或零個類型引數,但不能有任何其他數量。

範例

#

以下程式碼會產生此診斷訊息,因為 Map 模式 (<int>{}) 具有一個類型引數

dart
void f(Object x) {
  if (x case <int>{0: _}) {}
}

常見修正方式

#

新增或移除類型引數,直到有兩個或零個

dart
void f(Object x) {
  if (x case <int, int>{0: _}) {}
}

預期兩個_map類型引數

#

Map 字面量需要兩個或零個類型引數,但找到了 {0} 個。

描述

#

當 Map 字面量具有一個或多於兩個類型引數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 Map 字面量具有三個類型引數,但它可以有兩個或零個

dart
var m = <int, String, int>{};

常見修正方式

#

移除除了兩個以外的所有類型引數

dart
var m = <int, String>{};

匯出內部程式庫

#

程式庫「{0}」是內部的,不能被匯出。

描述

#

當分析器找到一個匯出指令,其 dart: URI 引用了內部程式庫時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 _interceptors 是一個內部程式庫

dart
export 'dart:_interceptors';

常見修正方式

#

移除匯出指令。

匯出舊版符號

#

符號「{0}」定義在舊版程式庫中,不能從啟用空值安全性的程式庫中重新匯出。

描述

#

當選擇加入空值安全性的程式庫匯出另一個程式庫,而匯出的程式庫選擇退出空值安全性時,分析器會產生此診斷訊息。

範例

#

給定一個選擇退出空值安全性的程式庫

dart
// @dart = 2.8
String s;

以下程式碼會產生此診斷訊息,因為它正在匯出選擇退出的程式庫中的符號

dart
export 'optedOut.dart';

class C {}

常見修正方式

#

如果可以,遷移匯出的程式庫,使其不需要選擇退出

dart
String? s;

如果無法遷移程式庫,則移除匯出

dart
class C {}

如果匯出的程式庫(選擇退出的那個)本身匯出了一個選擇加入的程式庫,那麼您的程式庫間接匯出選擇加入的程式庫中的符號是有效的。您可以通過在程式庫中的匯出指令中新增一個 hide 組合器來隱藏所有在選擇退出的程式庫中宣告的名稱來做到這一點。

匯出非程式庫

#

匯出的程式庫「{0}」不能有 part-of 指令。

描述

#

當匯出指令引用的是 part 而不是程式庫時,分析器會產生此診斷訊息。

範例

#

給定一個包含以下內容的檔案 part.dart

dart
part of lib;

以下程式碼會產生此診斷訊息,因為檔案 part.dart 是一個 part,而只有程式庫可以被匯出

dart
library lib;

export 'part.dart';

常見修正方式

#

移除匯出指令,或將 URI 更改為包含 part 的程式庫的 URI。

map中的運算式

#

表達式不能在 Map 字面量中使用。

描述

#

當分析器在看起來像 Map 字面量的東西中找到表達式,而不是 Map 條目時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息

dart
var map = <String, int>{'a': 0, 'b': 1, 'c'};

常見修正方式

#

如果表達式旨在計算條目中的鍵或值,請通過將表達式替換為鍵或值來修復此問題。例如

dart
var map = <String, int>{'a': 0, 'b': 1, 'c': 2};

擴充非類別

#

類別只能擴展其他類別。

描述

#

extends 子句包含一個被宣告為類別以外的東西的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 被宣告為函數

dart
void f() {}

class C extends f {}

常見修正方式

#

如果您希望類別擴展 Object 以外的類別,則將 extends 子句中的名稱替換為該類別的名稱

dart
void f() {}

class C extends B {}

class B {}

如果您希望類別擴展 Object,則移除 extends 子句

dart
void f() {}

class C {}

擴充功能作為運算式

#

擴展「{0}」不能用作表達式。

描述

#

當擴展的名稱在表達式中使用,而不是在擴展覆蓋中或限定對擴展的靜態成員的訪問時,分析器會產生此診斷訊息。由於類別定義了一種類型,因此類別的名稱可用於引用表示類別類型的 Type 實例。另一方面,擴展不定義類型,也不能用作類型字面量。

範例

#

以下程式碼會產生此診斷訊息,因為 E 是一個擴展

dart
extension E on int {
  static String m() => '';
}

var x = E;

常見修正方式

#

將擴展的名稱替換為可以被引用的名稱,例如在擴展上定義的靜態成員

dart
extension E on int {
  static String m() => '';
}

var x = E.m();

擴充功能衝突的靜態和實例

#

擴展不能定義靜態成員「{0}」和具有相同名稱的實例成員。

描述

#

當擴展宣告同時包含一個實例成員和一個具有相同名稱的靜態成員時,分析器會產生此診斷訊息。實例成員和靜態成員不能具有相同的名稱,因為不清楚在擴展主體內不限定地使用該名稱時,正在引用哪個成員。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 a 被用於兩個不同的成員

dart
extension E on Object {
  int get a => 0;
  static int a() => 0;
}

常見修正方式

#

重新命名或移除其中一個成員

dart
extension E on Object {
  int get a => 0;
  static int b() => 0;
}

擴充功能宣告抽象成員

#

擴展不能宣告抽象成員。

描述

#

當在擴展中宣告抽象宣告時,分析器會產生此診斷訊息。擴展只能宣告具體成員。

範例

#

以下程式碼會產生此診斷訊息,因為方法 a 沒有主體

dart
extension E on String {
  int a();
}

常見修正方式

#

為成員提供一個實現或移除它。

擴充功能宣告建構子

#

擴展不能宣告建構式。

描述

#

當在擴展中找到建構式宣告時,分析器會產生此診斷訊息。定義建構式是無效的,因為擴展不是類別,並且不可能創建擴展的實例。

範例

#

以下程式碼會產生此診斷訊息,因為 E 中存在建構式宣告

dart
extension E on String {
  E() : super();
}

常見修正方式

#

移除建構式或將其替換為靜態方法。

擴充功能宣告實例欄位

#

擴展不能宣告實例欄位。

描述

#

當在擴展中找到實例欄位宣告時,分析器會產生此診斷訊息。定義實例欄位是無效的,因為擴展只能新增行為,而不能新增狀態。

範例

#

以下程式碼會產生此診斷訊息,因為 s 是一個實例欄位

dart
extension E on String {
  String s;
}

常見修正方式

#

如果可以在不將值儲存在欄位中的情況下計算值,則嘗試使用 getter 或方法

dart
extension E on String {
  String get s => '';

  void s(String value) => print(s);
}

如果必須儲存值,但對於每個實例都相同,則嘗試使用靜態欄位

dart
extension E on String {
  static String s = '';
}

如果每個實例都需要儲存自己的值,則嘗試使用由靜態 Expando 支持的 getter 和 setter 對

dart
extension E on SomeType {
  static final _s = Expando<String>();

  String get s => _s[this] ?? '';
  set s(String value) => _s[this] = value;
}

擴充功能宣告物件成員

#

擴展不能宣告與 'Object' 宣告的成員同名的成員。

描述

#

當擴展宣告宣告了一個與類別 Object 中宣告的成員同名的成員時,分析器會產生此診斷訊息。這樣的成員永遠無法使用,因為總是先找到 Object 中的成員。

範例

#

以下程式碼會產生此診斷訊息,因為 toStringObject 定義

dart
extension E on String {
  String toString() => this;
}

常見修正方式

#

移除成員或重新命名它,使其名稱不與 Object 中的成員衝突

dart
extension E on String {
  String displayString() => this;
}

擴充功能覆寫存取靜態成員

#

擴展覆蓋不能用於訪問擴展中的靜態成員。

描述

#

當擴展覆蓋是靜態成員調用的接收者時,分析器會產生此診斷訊息。與類別中的靜態成員類似,擴展的靜態成員應使用擴展的名稱而不是擴展覆蓋來訪問。

範例

#

以下程式碼會產生此診斷訊息,因為 m 是靜態的

dart
extension E on String {
  static void m() {}
}

void f() {
  E('').m();
}

常見修正方式

#

將擴展覆蓋替換為擴展的名稱

dart
extension E on String {
  static void m() {}
}

void f() {
  E.m();
}

擴充功能覆寫引數不可賦值

#

擴展覆蓋「{0}」的引數類型不能賦值給擴展類型「{1}」。

描述

#

當擴展覆蓋的引數不能賦值給擴展所擴展的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 3 不是 String

dart
extension E on String {
  void method() {}
}

void f() {
  E(3).method();
}

常見修正方式

#

如果您正在使用正確的擴展,則更新引數以具有正確的類型

dart
extension E on String {
  void method() {}
}

void f() {
  E(3.toString()).method();
}

如果有另一個對引數類型有效的擴展,則替換擴展的名稱或解包裝引數,以便找到正確的擴展。

沒有存取的擴充功能覆寫

#

擴展覆蓋只能用於訪問實例成員。

描述

#

當找到一個擴展覆蓋,但它沒有被用於訪問擴展的成員之一時,分析器會產生此診斷訊息。擴展覆蓋語法沒有任何運行時語義;它僅控制在編譯時選擇哪個成員。

範例

#

以下程式碼會產生此診斷訊息,因為 E(i) 不是表達式

dart
extension E on int {
  int get a => 0;
}

void f(int i) {
  print(E(i));
}

常見修正方式

#

如果您想調用擴展的成員之一,則新增調用

dart
extension E on int {
  int get a => 0;
}

void f(int i) {
  print(E(i).a);
}

如果您不想調用成員,則解包裝引數

dart
extension E on int {
  int get a => 0;
}

void f(int i) {
  print(i);
}

具有串聯的擴充功能覆寫

#

擴展覆蓋沒有值,因此它們不能用作級聯表達式的接收者。

描述

#

當擴展覆蓋用作級聯表達式的接收者時,分析器會產生此診斷訊息。級聯表達式 e..m 的值是接收者 e 的值,但擴展覆蓋不是表達式,也沒有值。

範例

#

以下程式碼會產生此診斷訊息,因為 E(3) 不是表達式

dart
extension E on int {
  void m() {}
}
f() {
  E(3)..m();
}

常見修正方式

#

使用 . 而不是 ..

dart
extension E on int {
  void m() {}
}
f() {
  E(3).m();
}

如果有多個級聯訪問,您需要為每個訪問複製擴展覆蓋。

具有_super_形式參數的擴充功能類型建構子

#

擴展類型建構式不能宣告 super 形式參數。

描述

#

當擴展類型中的建構式具有 super 參數時,分析器會產生此診斷訊息。Super 參數是無效的,因為擴展類型沒有超類別。

範例

#

以下程式碼會產生此診斷訊息,因為具名建構式 n 包含一個 super 參數

dart
extension type E(int i) {
  E.n(this.i, super.foo);
}

常見修正方式

#

如果您需要該參數,請將 super 參數替換為常規參數

dart
extension type E(int i) {
  E.n(this.i, String foo);
}

如果您不需要該參數,則移除 super 參數

dart
extension type E(int i) {
  E.n(this.i);
}

具有_super_調用的擴充功能類型建構子

#

擴展類型建構式不能包含 super 初始化器。

描述

#

當擴展類型中的建構式在初始化器列表中包含對 super 建構式的調用時,分析器會產生此診斷訊息。由於擴展類型沒有超類別,因此沒有建構式可以調用。

範例

#

以下程式碼會產生此診斷訊息,因為建構式 E.n 在其初始化器列表中調用了一個 super 建構式

dart
extension type E(int i) {
  E.n() : i = 0, super.n();
}

常見修正方式

#

移除對 super 建構式的調用

dart
extension type E(int i) {
  E.n() : i = 0;
}

擴充功能類型宣告實例欄位

#

擴展類型不能宣告實例欄位。

描述

#

當擴展類型宣告的主體中存在欄位宣告時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴展類型 E 宣告了一個名為 f 的欄位

dart
extension type E(int i) {
  final int f = 0;
}

常見修正方式

#

如果您不需要該欄位,則移除它或將其替換為 getter 和/或 setter

dart
extension type E(int i) {
  int get f => 0;
}

如果您需要該欄位,則將擴展類型轉換為類別

dart
class E {
  final int i;

  final int f = 0;

  E(this.i);
}

擴充功能類型宣告物件成員

#

擴展類型不能宣告與 'Object' 宣告的成員同名的成員。

描述

#

當擴展類型宣告的主體包含一個與 Object 宣告的成員之一同名的成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 Object 已經定義了一個名為 hashCode 的成員

dart
extension type E(int i) {
  int get hashCode => 0;
}

常見修正方式

#

如果您需要具有已實現語義的成員,則重新命名成員

dart
extension type E(int i) {
  int get myHashCode => 0;
}

如果您不需要具有已實現語義的成員,則移除成員

dart
extension type E(int i) {}

擴充功能類型實作了不允許的類型

#

擴展類型不能實現「{0}」。

描述

#

當擴展類型實現了它不允許實現的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴展類型不能實現類型 dynamic

dart
extension type A(int i) implements dynamic {}

常見修正方式

#

從 implements 子句中移除不允許的類型

dart
extension type A(int i) {}

擴充功能類型實作了自身

#

擴展類型不能實現自身。

描述

#

當擴展類型直接或間接地實現自身時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴展類型 A 直接實現了自身

dart
extension type A(int i) implements A {}

以下程式碼會產生此診斷訊息,因為擴展類型 A 間接地實現了自身 (通過 B)

dart
extension type A(int i) implements B {}

extension type B(int i) implements A {}

常見修正方式

#

通過從至少一個涉及循環的類型的 implements 子句中移除一個類型來打破循環

dart
extension type A(int i) implements B {}

extension type B(int i) {}

擴充功能類型實作了非超類型

#

「{0}」不是「{1}」的超類型,即表示類型。

描述

#

當擴展類型實現的類型不是表示類型的超類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴展類型 A 實現了 String,但 String 不是表示類型 int 的超類型

dart
extension type A(int i) implements String {}

常見修正方式

#

如果表示類型是正確的,則移除或替換 implements 子句中的類型

dart
extension type A(int i) {}

如果表示類型不正確,則將其替換為正確的類型

dart
extension type A(String s) implements String {}

擴充功能類型實作了表示法非超類型

#

「{0}」,「{1}」的表示類型,不是「{2}」,「{3}」的表示類型的超類型。

描述

#

當擴展類型實現另一個擴展類型,並且被實現的擴展類型的表示類型不是實現擴展類型的表示類型的子類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴展類型 B 實現了 A,但 A 的表示類型 (num) 不是 B 的表示類型 (String) 的子類型

dart
extension type A(num i) {}

extension type B(String s) implements A {}

常見修正方式

#

更改兩個擴展類型的表示類型,使被實現的類型的表示類型成為實現類型的表示類型的超類型

dart
extension type A(num i) {}

extension type B(int n) implements A {}

或從 implements 子句中移除被實現的類型

dart
extension type A(num i) {}

extension type B(String s) {}

擴充功能類型繼承的成員衝突

#

擴展類型「{0}」從已實現的類型中具有多個名為「{1}」的不同成員。

描述

#

分析器會在擴充類型實作兩個或多個其他類型,且至少有其中兩個類型宣告了名稱相同的成員時,產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充類型 C 同時實作了 AB,而兩者都宣告了名為 m 的成員

dart
class A {
  void m() {}
}

extension type B(A a) {
  void m() {}
}

extension type C(A a) implements A, B {}

常見修正方式

#

如果擴充類型不需要實作所有列出的類型,則移除除了其中一個引入衝突成員的類型之外的所有類型

dart
class A {
  void m() {}
}

extension type B(A a) {
  void m() {}
}

extension type C(A a) implements A {}

如果擴充類型需要實作所有列出的類型,但您可以重新命名這些類型中的成員,則為衝突的成員提供唯一的名稱

dart
class A {
  void m() {}
}

extension type B(A a) {
  void n() {}
}

extension type C(A a) implements A, B {}

擴充功能類型表示法取決於自身

#

擴充類型的表示法不能依賴自身。

描述

#

當擴充類型的表示類型直接或間接地依賴擴充類型自身時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充類型 A 的表示類型直接依賴於 A

dart
extension type A(A a) {}

以下兩個程式碼範例會產生此診斷訊息,因為擴充類型 A 的表示類型透過擴充類型 B 間接地依賴於 A

dart
extension type A(B b) {}

extension type B(A a) {}
dart
extension type A(List<B> b) {}

extension type B(List<A> a) {}

常見修正方式

#

透過為循環中的至少一個類型選擇不同的表示類型來移除依賴性

dart
extension type A(String s) {}

擴充功能類型表示法類型為底部

#

表示類型不能是 bottom type。

描述

#

當擴充類型的表示類型是 bottom type Never 時,分析器會產生此診斷訊息。類型 Never 不能作為擴充類型的表示類型,因為沒有可以擴充的值。

範例

#

以下程式碼會產生此診斷訊息,因為擴充類型 E 的表示類型是 Never

dart
extension type E(Never n) {}

常見修正方式

#

將擴充類型替換為不同的類型

dart
extension type E(String s) {}

具有抽象成員的擴充功能類型

#

'{0}' 必須有方法主體,因為 '{1}' 是一個擴充類型。

描述

#

當擴充類型宣告抽象成員時,分析器會產生此診斷訊息。由於擴充類型成員的參考是靜態解析的,因此擴充類型中的抽象成員永遠無法執行。

範例

#

以下程式碼會產生此診斷訊息,因為擴充類型 E 中的方法 m 是抽象的

dart
extension type E(String s) {
  void m();
}

常見修正方式

#

如果成員旨在可執行,則提供成員的實作

dart
extension type E(String s) {
  void m() {}
}

如果成員不旨在可執行,則移除它

dart
extension type E(String s) {}

具有初始化器的外部

#

外部欄位不能有初始化器。

外部變數不能有初始化器。

描述

#

當標記為關鍵字 external 的欄位或變數具有初始化器,或者當外部欄位在建構子中初始化時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為外部欄位 x 在初始化器中被賦予值

dart
class C {
  external int x;
  C() : x = 0;
}

以下程式碼會產生此診斷訊息,因為外部欄位 x 具有初始化器

dart
class C {
  external final int x = 0;
}

以下程式碼會產生此診斷訊息,因為外部頂層變數 x 具有初始化器

dart
external final int x = 0;

常見修正方式

#

移除初始化器

dart
class C {
  external final int x;
}

struct_欄位上多餘的註解

#

結構類別中的欄位必須恰好有一個指示原生類型的註解。

描述

#

Struct 子類別中的欄位具有多個描述欄位原生類型的註解時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 x 有兩個描述欄位原生類型的註解

dart
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  @Int16()
  external int x;
}

常見修正方式

#

移除除了其中一個註解之外的所有註解

dart
import 'dart:ffi';
final class C extends Struct {
  @Int32()
  external int x;
}

額外的位置引數

#

位置引數過多:預期 {0} 個,但找到 {1} 個。

描述

#

當方法或函數調用具有比方法或函數允許的位置引數更多的引數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 定義了 2 個參數,但使用 3 個引數調用

dart
void f(int a, int b) {}
void g() {
  f(1, 2, 3);
}

常見修正方式

#

移除與參數不對應的引數

dart
void f(int a, int b) {}
void g() {
  f(1, 2);
}

額外的位置引數可能是具名的

#

位置引數過多:預期 {0} 個,但找到 {1} 個。

描述

#

當方法或函數調用具有比方法或函數允許的位置引數更多的引數時,分析器會產生此診斷訊息,但方法或函數定義了具名參數。

範例

#

以下程式碼會產生此診斷訊息,因為 f 定義了 2 個位置參數,但有一個具名參數可以用於第三個引數

dart
void f(int a, int b, {int? c}) {}
void g() {
  f(1, 2, 3);
}

常見修正方式

#

如果某些引數應該是具名參數的值,則在引數之前新增名稱

dart
void f(int a, int b, {int? c}) {}
void g() {
  f(1, 2, c: 3);
}

否則,移除與位置參數不對應的引數

dart
void f(int a, int b, {int? c}) {}
void g() {
  f(1, 2);
}

carray額外的大小註解

#

'Array' 必須恰好有一個 'Array' 註解。

描述

#

Struct 子類別中的欄位具有多個描述原生陣列大小的註解時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 a0 有兩個指定原生陣列大小的註解

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(4)
  @Array(8)
  external Array<Uint8> a0;
}

常見修正方式

#

移除除了其中一個註解之外的所有註解

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8)
  external Array<Uint8> a0;
}

ffi_native無效的重複預設資源

#

一個程式庫最多只能有一個 @DefaultAsset 註解。

描述

#

當程式庫指令具有多個與其關聯的 DefaultAsset 註解時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為程式庫指令具有兩個與其關聯的 DefaultAsset 註解

dart
@DefaultAsset('a')
@DefaultAsset('b')
library;

import 'dart:ffi';

常見修正方式

#

移除除了其中一個 DefaultAsset 註解之外的所有註解

dart
@DefaultAsset('a')
library;

import 'dart:ffi';

ffi_native無效的多個註解

#

原生函數和欄位必須恰好有一個 @Native 註解。

描述

#

當單一宣告上有超過一個 Native 註解時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函數 f 有兩個與其關聯的 Native 註解

dart
import 'dart:ffi';

@Native<Int32 Function(Int32)>()
@Native<Int32 Function(Int32)>(isLeaf: true)
external int f(int v);

常見修正方式

#

移除除了其中一個註解之外的所有註解

dart
import 'dart:ffi';

@Native<Int32 Function(Int32)>(isLeaf: true)
external int f(int v);

ffi_native必須是外部的

#

原生函數必須宣告為 external。

描述

#

當註解為 @Native 的函數未標記為 external 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函數 free 註解為 @Native,但該函數未標記為 external

dart
import 'dart:ffi';

@Native<Void Function(Pointer<Void>)>()
void free(Pointer<Void> ptr) {}

常見修正方式

#

如果函數是原生函數,則在返回類型之前新增修飾詞 external

dart
import 'dart:ffi';

@Native<Void Function(Pointer<Void>)>()
external void free(Pointer<Void> ptr);

ffi_native非預期的參數數量

#

Native 註解參數的數量不符預期。預期 {0} 個,但有 {1} 個。

描述

#

當用作 @Native 註解的類型引數的函數類型中的參數數量與被註解的函數中的參數數量不符時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為用作 @Native 註解的類型引數的函數類型 (Void Function(Double)) 有一個引數,而被註解的函數的類型 (void f(double, double)) 有兩個引數

dart
import 'dart:ffi';

@Native<Void Function(Double)>(symbol: 'f')
external void f(double x, double y);

常見修正方式

#

如果被註解的函數是正確的,則更新 @Native 註解中的函數類型以匹配

dart
import 'dart:ffi';

@Native<Void Function(Double, Double)>(symbol: 'f')
external void f(double x, double y);

如果 @Native 註解中的函數類型是正確的,則更新被註解的函數以匹配

dart
import 'dart:ffi';

@Native<Void Function(Double)>(symbol: 'f')
external void f(double x);

ffi_native具有接收器的非預期參數數量

#

Native 註解參數的數量不符預期。預期 {0} 個,但有 {1} 個。原生實例方法註解必須將接收器作為第一個引數。

描述

#

當原生方法的 @Native 註解上使用的類型引數不包含方法接收器的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 @Native 註解上的類型引數 (Void Function(Double)) 不包含方法接收器的類型

dart
import 'dart:ffi';

class C {
  @Native<Void Function(Double)>()
  external void f(double x);
}

常見修正方式

#

新增一個初始參數,其類型與宣告原生方法的類別相同

dart
import 'dart:ffi';

class C {
  @Native<Void Function(C, Double)>()
  external void f(double x);
}

由多個初始化器初始化的欄位

#

欄位 '{0}' 不能在同一個建構子中初始化兩次。

描述

#

當建構子的初始化列表多次初始化一個欄位時,分析器會產生此診斷訊息。允許兩個初始化器沒有任何意義,因為只會保留最後一個值。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 f 正在被初始化兩次

dart
class C {
  int f;

  C() : f = 0, f = 1;
}

常見修正方式

#

移除其中一個初始化器

dart
class C {
  int f;

  C() : f = 0;
}

在初始化器和宣告中初始化的欄位

#

如果欄位是 final 且已在其宣告時初始化,則不能在建構子中初始化。

描述

#

當 final 欄位在欄位的宣告和建構子中的初始化器中都初始化時,分析器會產生此診斷訊息。Final 欄位只能賦值一次,因此不能在兩個地方都初始化。

範例

#

以下程式碼會產生此診斷訊息,因為 f

dart
class C {
  final int f = 0;
  C() : f = 1;
}

常見修正方式

#

如果初始化不依賴於傳遞給建構子的任何值,並且如果所有建構子都需要將欄位初始化為相同的值,則從建構子中移除初始化器

dart
class C {
  final int f = 0;
  C();
}

如果初始化依賴於傳遞給建構子的值,或者如果不同的建構子需要以不同的方式初始化欄位,則從欄位的宣告中移除初始化器

dart
class C {
  final int f;
  C() : f = 1;
}

在參數和初始化器中初始化的欄位

#

欄位不能在參數列表和初始化器中同時初始化。

描述

#

當欄位在參數列表和建構子的初始化列表中都初始化時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 f 同時被初始化形式參數和初始化列表初始化

dart
class C {
  int f;

  C(this.f) : f = 0;
}

常見修正方式

#

如果應該由參數初始化欄位,則移除初始化列表中的初始化

dart
class C {
  int f;

  C(this.f);
}

如果應該在初始化列表中初始化欄位並且不需要參數,則移除參數

dart
class C {
  int f;

  C() : f = 0;
}

如果應該在初始化列表中初始化欄位並且需要參數,則將其設為一般參數

dart
class C {
  int f;

  C(int g) : f = g * 2;
}

欄位初始化器_factory_建構子

#

初始化形式參數不能用於 factory 建構子。

描述

#

當 factory 建構子具有初始化形式參數時,分析器會產生此診斷訊息。Factory 建構子不能將值賦給欄位,因為沒有建立實例;因此,沒有欄位可以賦值。

範例

#

以下程式碼會產生此診斷訊息,因為 factory 建構子使用了初始化形式參數

dart
class C {
  int? f;

  factory C(this.f) => throw 0;
}

常見修正方式

#

將初始化形式參數替換為一般參數

dart
class C {
  int? f;

  factory C(int f) => throw 0;
}

struct中的欄位初始化器

#

'Struct' 和 'Union' 子類別中的建構子不能有欄位初始化器。

描述

#

StructUnion 的子類別中的建構子具有一個或多個欄位初始化器時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 有一個具有欄位 f 初始化器的建構子

dart
// @dart = 2.9
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  int f;

  C() : f = 0;
}

常見修正方式

#

移除欄位初始化器

dart
// @dart = 2.9
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  int f;

  C();
}

欄位初始化器不可賦值

#

在 const 建構子中,初始化器類型 '{0}' 無法賦值給欄位類型 '{1}'。

初始化器類型 '{0}' 無法賦值給欄位類型 '{1}'。

描述

#

當建構子的初始化列表將欄位初始化為無法賦值給該欄位的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 0 的類型為 int,而 int 無法賦值給類型為 String 的欄位

dart
class C {
  String s;

  C() : s = 0;
}

常見修正方式

#

如果欄位的類型是正確的,則變更賦給它的值,使該值具有有效的類型

dart
class C {
  String s;

  C() : s = '0';
}

如果值的類型是正確的,則變更欄位的類型以允許賦值

dart
class C {
  int s;

  C() : s = 0;
}

建構子外部的欄位初始化器

#

欄位形式參數只能在建構子中使用。

初始化形式參數只能在建構子中使用。

描述

#

當初始化形式參數用於建構子以外的任何參數列表時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為初始化形式參數 this.x 正在方法 m 中使用

dart
class A {
  int x = 0;

  m([this.x = 0]) {}
}

常見修正方式

#

將初始化形式參數替換為一般參數,並在方法主體中賦值給欄位

dart
class A {
  int x = 0;

  m([int x = 0]) {
    this.x = x;
  }
}

欄位初始化器重新導向建構子

#

重新導向建構子不能有欄位初始化器。

描述

#

當重新導向建構子在物件中初始化欄位時,分析器會產生此診斷訊息。這是不允許的,因為在應該初始化欄位時,尚未建立具有該欄位的實例。

範例

#

以下程式碼會產生此診斷訊息,因為重新導向到建構子 C 的建構子 C.zero 具有初始化欄位 f 的初始化形式參數

dart
class C {
  int f;

  C(this.f);

  C.zero(this.f) : this(f);
}

以下程式碼會產生此診斷訊息,因為重新導向到建構子 C 的建構子 C.zero 具有初始化欄位 f 的初始化器

dart
class C {
  int f;

  C(this.f);

  C.zero() : f = 0, this(1);
}

常見修正方式

#

如果初始化是由初始化形式參數完成的,則使用一般參數

dart
class C {
  int f;

  C(this.f);

  C.zero(int f) : this(f);
}

如果初始化是在初始化器中完成的,則移除初始化器

dart
class C {
  int f;

  C(this.f);

  C.zero() : this(0);
}

欄位初始化形式參數不可賦值

#

參數類型 '{0}' 與欄位類型 '{1}' 不相容。

描述

#

當初始化形式參數的類型無法賦值給正在初始化的欄位的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為初始化形式參數的類型為 String,但欄位的類型為 int。參數的類型必須是欄位類型的子類型。

dart
class C {
  int f;

  C(String this.f);
}

常見修正方式

#

如果欄位的類型不正確,則變更欄位的類型以匹配參數的類型,並考慮從參數中移除類型

dart
class C {
  String f;

  C(this.f);
}

如果參數的類型不正確,則移除參數的類型

dart
class C {
  int f;

  C(this.f);
}

如果欄位和參數的類型都正確,則使用初始化器而不是初始化形式參數,將參數值轉換為正確類型的值

dart
class C {
  int f;

  C(String s) : f = int.parse(s);
}

具有初始化器的_struct中的欄位

#

'Struct' 和 'Union' 子類別中的欄位不能有初始化器。

描述

#

Struct 子類別中的欄位具有初始化器時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 p 具有初始化器

dart
// @dart = 2.9
import 'dart:ffi';

final class C extends Struct {
  Pointer p = nullptr;
}

常見修正方式

#

移除初始化器

dart
// @dart = 2.9
import 'dart:ffi';

final class C extends Struct {
  Pointer p;
}

struct中的欄位必須是外部的

#

'Struct' 和 'Union' 子類別的欄位必須標記為 external。

描述

#

StructUnion 的子類別中的欄位未標記為 external 時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 a 未標記為 external

dart
import 'dart:ffi';

final class C extends Struct {
  @Int16()
  int a;
}

常見修正方式

#

新增必要的 external 修飾詞

dart
import 'dart:ffi';

final class C extends Struct {
  @Int16()
  external int a;
}

在宣告和建構子中初始化的_final

#

'{0}' 是 final,並且在宣告時已賦予值,因此不能設定為新值。

描述

#

當 final 欄位被初始化兩次時,分析器會產生此診斷訊息:一次在其宣告的位置,一次透過建構子的參數。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 f 被初始化了兩次

dart
class C {
  final int f = 0;

  C(this.f);
}

常見修正方式

#

如果欄位在所有實例中都應該具有相同的值,則移除參數列表中的初始化

dart
class C {
  final int f = 0;

  C();
}

如果欄位在不同的實例中可以具有不同的值,則移除宣告中的初始化

dart
class C {
  final int f;

  C(this.f);
}

final_未初始化

#

final 變數 '{0}' 必須初始化。

描述

#

當 final 欄位或變數未初始化時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 x 沒有初始化器

dart
final x;

常見修正方式

#

對於變數和靜態欄位,您可以新增初始化器

dart
final x = 0;

對於實例欄位,您可以新增初始化器,如先前的範例所示,或者您可以在每個建構子中初始化欄位。您可以使用初始化形式參數來初始化欄位

dart
class C {
  final int x;
  C(this.x);
}

您也可以透過在建構子中使用初始化器來初始化欄位

dart
class C {
  final int x;
  C(int y) : x = y * 2;
}

final_未初始化_建構子

#

所有 final 變數都必須初始化,但 '{0}' 和 '{1}' 沒有。

所有 final 變數都必須初始化,但 '{0}' 沒有。

所有 final 變數都必須初始化,但 '{0}'、'{1}' 和其他 {2} 個沒有。

描述

#

當類別定義了一個或多個沒有初始化器的 final 實例欄位,並且至少有一個建構子沒有初始化這些欄位時,分析器會產生此診斷訊息。所有 final 實例欄位都必須在建立實例時初始化,可以是透過欄位的初始化器或透過建構子。

範例

#

下列程式碼會產生此診斷訊息

dart
class C {
  final String value;

  C();
}

常見修正方式

#

如果值應該直接傳遞到建構子中,則使用初始化形式參數來初始化欄位 value

dart
class C {
  final String value;

  C(this.value);
}

如果值應該從呼叫者提供的值間接計算而來,則新增一個參數並包含一個初始化器

dart
class C {
  final String value;

  C(Object o) : value = o.toString();
}

如果欄位的值不依賴於可以傳遞給建構子的值,則在欄位宣告中為欄位新增一個初始化器

dart
class C {
  final String value = '';

  C();
}

如果欄位的值不依賴於可以傳遞給建構子的值,但不同的建構子需要將其初始化為不同的值,則在初始化列表中為欄位新增一個初始化器

dart
class C {
  final String value;

  C() : value = '';

  C.named() : value = 'c';
}

但是,如果該值對於所有實例都相同,則考慮使用靜態欄位而不是實例欄位

dart
class C {
  static const String value = '';

  C();
}

flutter_欄位不是_map

#

'flutter' 欄位的值預期為 map。

描述

#

flutter 鍵的值不是 map 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為頂層 flutter 鍵的值是字串

yaml
name: example
flutter: true

常見修正方式

#

如果您需要指定 Flutter 特定的選項,則將值變更為 map

yaml
name: example
flutter:
  uses-material-design: true

如果您不需要指定 Flutter 特定的選項,則移除 flutter

yaml
name: example

for-in_的無效元素類型

#

'for' 迴圈中使用的類型 '{0}' 必須實作 '{1}',且其類型引數可以賦值給 '{2}'。

描述

#

當 for-in 迴圈中的 IterableStream 具有無法賦值給迴圈變數的元素類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 <String>[] 的元素類型為 String,而 String 無法賦值給 e 的類型 (int)

dart
void f() {
  for (int e in <String>[]) {
    print(e);
  }
}

常見修正方式

#

如果迴圈變數的類型是正確的,則更新 iterable 的類型

dart
void f() {
  for (int e in <int>[]) {
    print(e);
  }
}

如果 iterable 的類型是正確的,則更新迴圈變數的類型

dart
void f() {
  for (String e in <String>[]) {
    print(e);
  }
}

for-in_的無效類型

#

'for' 迴圈中使用的類型 '{0}' 必須實作 '{1}'。

描述

#

當 for-in 迴圈中 in 後面的表達式具有不是 Iterable 子類別的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 mMap,而 Map 不是 Iterable 的子類別

dart
void f(Map<String, String> m) {
  for (String s in m) {
    print(s);
  }
}

常見修正方式

#

將表達式替換為產生 iterable 值的表達式

dart
void f(Map<String, String> m) {
  for (String s in m.values) {
    print(s);
  }
}

具有_const_變數的_for-in

#

for-in 迴圈變數不能是 'const'。

描述

#

當在 for-in 迴圈中宣告的迴圈變數被宣告為 const 時,分析器會產生此診斷訊息。變數不能是 const,因為該值無法在編譯時計算。

範例

#

以下程式碼會產生此診斷訊息,因為迴圈變數 x 被宣告為 const

dart
void f() {
  for (const x in [0, 1, 2]) {
    print(x);
  }
}

常見修正方式

#

如果存在類型註解,則從宣告中移除 const 修飾詞。

如果沒有類型,則將 const 修飾詞替換為 finalvar 或類型註解

dart
void f() {
  for (final x in [0, 1, 2]) {
    print(x);
  }
}

dynamic上的泛型方法類型具現化

#

類型為 'dynamic' 的接收器的成員方法 tear-off 不能有類型引數。

描述

#

當從類型為 dynamic 的接收器 tear-off 實例方法,並且 tear-off 包含類型引數時,分析器會產生此診斷訊息。由於分析器無法知道該方法有多少個類型參數,或者它是否具有任何類型參數,因此無法驗證類型引數是否正確。因此,不允許使用類型引數。

範例

#

以下程式碼會產生此診斷訊息,因為 p 的類型為 dynamic,並且 m 的 tear-off 具有類型引數

dart
void f(dynamic list) {
  list.fold<int>;
}

常見修正方式

#

如果您可以使用比 dynamic 更具體的類型,則變更接收器的類型

dart
void f(List<Object> list) {
  list.fold<int>;
}

如果您無法使用更具體的類型,則移除類型引數

dart
void f(dynamic list) {
  list.cast;
}

泛型_struct_子類別

#

類別 '{0}' 無法擴展 'Struct' 或 'Union',因為 '{0}' 是泛型類別。

描述

#

StructUnion 的子類別具有類型參數時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為類別 S 定義了類型參數 T

dart
import 'dart:ffi';

final class S<T> extends Struct {
  external Pointer notEmpty;
}

常見修正方式

#

從類別中移除類型參數

dart
import 'dart:ffi';

final class S extends Struct {
  external Pointer notEmpty;
}

getter不是_setter類型的子類型

#

getter '{0}' 的返回類型為 '{1}',這不是其 setter '{3}' 的類型 '{2}' 的子類型。

描述

#

當 getter 的返回類型不是與其同名的 setter 的參數類型的子類型時,分析器會產生此診斷訊息。

子類型關係是一個要求,無論 getter 和 setter 是否在同一個類別中,或者它們中的一個是否在另一個的父類別中。

範例

#

以下程式碼會產生此診斷訊息,因為 getter x 的返回類型為 num,setter x 的參數類型為 int,而 num 不是 int 的子類型

dart
class C {
  num get x => 0;

  set x(int y) {}
}

常見修正方式

#

如果 getter 的類型是正確的,則變更 setter 的類型

dart
class C {
  num get x => 0;

  set x(num y) {}
}

如果 setter 的類型是正確的,則變更 getter 的類型

dart
class C {
  int get x => 0;

  set x(int y) {}
}

非法的_async_產生器傳回類型

#

標記為 'async*' 的函數必須具有作為 'Stream' 的超類型的返回類型,其中 'T' 為某個類型。

描述

#

當函數的主體具有 async* 修飾詞,即使函數的返回類型不是 StreamStream 的超類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函數 f 的主體具有 'async*' 修飾詞,即使返回類型 int 不是 Stream 的超類型

dart
int f() async* {}

常見修正方式

#

如果函數應該是非同步的,則將返回類型變更為 StreamStream 的超類型

dart
Stream<int> f() async* {}

如果函數應該是同步的,則移除 async* 修飾詞

dart
int f() => 0;

非法的_async傳回類型

#

標記為 'async' 的函數必須具有作為 'Future' 的超類型的返回類型。

描述

#

當函數的主體具有 async 修飾詞,即使函數的返回類型無法賦值給 Future 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函數 f 的主體具有 async 修飾詞,即使返回類型無法賦值給 Future

dart
int f() async {
  return 0;
}

常見修正方式

#

如果函數應該是非同步的,則將返回類型變更為可賦值給 Future 的類型

dart
Future<int> f() async {
  return 0;
}

如果函數應該是同步的,則移除 async 修飾詞

dart
int f() => 0;

非法的具體列舉成員

#

名為 '{0}' 的具體實例成員不能在實作 'Enum' 的類別中宣告。

名為 '{0}' 的具體實例成員不能從實作 'Enum' 的類別中的 '{1}' 繼承。

描述

#

當列舉宣告、實作 Enum 的類別,或具有 Enum 超類別約束的 mixin,宣告或繼承名為 indexhashCode== 的具體實例成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列舉 E 宣告了一個名為 index 的實例 getter

dart
enum E {
  v;

  int get index => 0;
}

以下程式碼會產生此診斷訊息,因為實作 Enum 的類別 C 宣告了一個名為 hashCode 的實例欄位

dart
abstract class C implements Enum {
  int hashCode = 0;
}

以下程式碼會產生此診斷訊息,因為透過類別 A 間接實作 Enum 的類別 C 宣告了一個名為 hashCode 的實例 getter

dart
abstract class A implements Enum {}

abstract class C implements A {
  int get hashCode => 0;
}

以下程式碼會產生此診斷訊息,因為在 on 子句中具有 Enum 的 mixin M 宣告了一個明確的運算子 ==

dart
mixin M on Enum {
  bool operator ==(Object other) => false;
}

常見修正方式

#

重新命名衝突的成員

dart
enum E {
  v;

  int get getIndex => 0;
}

非法的列舉值

#

名為 'values' 的實例成員不能在實作 'Enum' 的類別中宣告。

名為 'values' 的實例成員不能從實作 'Enum' 的類別中的 '{0}' 繼承。

描述

#

當實作 Enum 的類別或具有 Enum 超類別約束的 mixin 具有名為 values 的實例成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為實作 Enum 的類別 C 宣告了一個名為 values 的實例欄位

dart
abstract class C implements Enum {
  int get values => 0;
}

以下程式碼會產生此診斷訊息,因為實作 Enum 的類別 BA 繼承了一個名為 values 的實例方法

dart
abstract class A {
  int values() => 0;
}

abstract class B extends A implements Enum {}

常見修正方式

#

變更衝突成員的名稱

dart
abstract class C implements Enum {
  int get value => 0;
}

非法的_sync_產生器傳回類型

#

標記為 'sync*' 的函數必須具有作為 'Iterable' 的超類型的返回類型,其中 'T' 為某個類型。

描述

#

分析器會在函數的主體具有 sync* 修飾詞,即使函數的返回類型不是 IterableIterable 的超類型時,產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函數 f 的主體具有 'sync*' 修飾詞,即使返回類型 int 不是 Iterable 的超類型

dart
int f() sync* {}

常見修正方式

#

如果函數應該返回 iterable,則將返回類型變更為 IterableIterable 的超類型

dart
Iterable<int> f() sync* {}

如果函數應該返回單一值,則移除 sync* 修飾詞

dart
int f() => 0;

實作非類別

#

類別和 mixin 只能實作其他類別和 mixin。

描述

#

當在類別或 mixin 宣告的 implements 子句中使用的名稱被定義為類別或 mixin 以外的其他內容時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 x 是一個變數而不是類別或 mixin

dart
var x;
class C implements x {}

常見修正方式

#

如果該名稱是已經匯入的現有類別或 mixin 的名稱,則為匯入新增前綴,以便該名稱的本地定義不會遮蔽匯入的名稱。

如果該名稱是未匯入的現有類別或 mixin 的名稱,則為宣告它的程式庫新增帶有前綴的匯入。

否則,將 implements 子句中的名稱替換為現有類別或 mixin 的名稱,或從 implements 子句中移除該名稱。

重複實作

#

'{0}' 只能實作一次。

描述

#

當在 implements 子句中多次指定同一個類別時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 A 在列表中出現兩次

dart
class A {}
class B implements A, A {}

常見修正方式

#

移除除了其中一個類別名稱之外的所有名稱

dart
class A {}
class B implements A {}

實作父類別

#

'{0}' 不能同時在 'extends' 和 'implements' 子句中使用。

'{0}' 不能同時在 'extends' 和 'with' 子句中使用。

描述

#

當類別在類別宣告的 extends 子句中列出,並且同時在同一個宣告的 implementswith 子句中列出時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 A 同時用於類別 Bextendsimplements 子句中

dart
class A {}

class B extends A implements A {}

以下程式碼會產生此診斷訊息,因為類別 A 同時用於類別 Bextendswith 子句中

dart
mixin class A {}

class B extends A with A {}

常見修正方式

#

如果您想要從類別繼承實作,則從 implements 子句中移除該類別

dart
class A {}

class B extends A {}

如果您不想要從類別繼承實作,則移除 extends 子句

dart
class A {}

class B implements A {}

隱含_super_初始化器遺失引數

#

從 '{0}' 隱含調用的未命名建構子具有必要參數。

描述

#

當建構子隱含調用來自父類別的未命名建構子,父類別的未命名建構子具有必要參數,並且沒有與必要參數對應的 super 參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 B 中的未命名建構子隱含調用類別 A 中的未命名建構子,但 A 中的建構子具有名為 x 的必要位置參數

dart
class A {
  A(int x);
}

class B extends A {
  B();
}

以下程式碼會產生此診斷訊息,因為類別 B 中的未命名建構子隱含調用類別 A 中的未命名建構子,但 A 中的建構子具有名為 x 的必要具名參數

dart
class A {
  A({required int x});
}

class B extends A {
  B();
}

常見修正方式

#

如果您可以在子類別的建構子中新增參數,則新增與父類別建構子中必要參數對應的 super 參數。新的參數可以是必要的

dart
class A {
  A({required int x});
}

class B extends A {
  B({required super.x});
}

或者它可以是選用的

dart
class A {
  A({required int x});
}

class B extends A {
  B({super.x = 0});
}

如果您無法在子類別的建構子中新增參數,則新增具有必要引數的明確 super 建構子調用

dart
class A {
  A(int x);
}

class B extends A {
  B() : super(0);
}

初始化器中隱含的_this_參考

#

實例成員 '{0}' 無法在初始化器中存取。

描述

#

當分析器在建構子的初始化列表中找到對實例成員的參考時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 defaultX 是一個實例成員

dart
class C {
  int x;

  C() : x = defaultX;

  int get defaultX => 0;
}

常見修正方式

#

如果成員可以設為靜態,則這樣做

dart
class C {
  int x;

  C() : x = defaultX;

  static int get defaultX => 0;
}

如果不是,則將初始化器中的參考替換為不使用實例成員的不同表達式

dart
class C {
  int x;

  C() : x = 0;

  int get defaultX => 0;
}

具有載入函式的延遲載入程式庫匯入

#

匯入的程式庫定義了一個名為 'loadLibrary' 的頂層函數,該函數被延遲此程式庫而隱藏。

描述

#

當宣告了名為 loadLibrary 的函數的程式庫使用延遲匯入來匯入時,分析器會產生此診斷訊息。延遲匯入引入了一個名為 loadLibrary 的隱含函數。此函數用於載入延遲程式庫的內容,並且隱含函數會隱藏延遲程式庫中的明確宣告。

有關更多資訊,請查看 延遲載入程式庫

範例

#

給定一個定義了名為 loadLibrary 的函數的檔案 a.dart

dart
void loadLibrary(Library library) {}

class Library {}

以下程式碼會產生此診斷訊息,因為 a.loadLibrary 的隱含宣告正在隱藏 a.dartloadLibrary 的明確宣告

dart
import 'a.dart' deferred as a;

void f() {
  a.Library();
}

常見修正方式

#

如果不需要延遲匯入匯入的程式庫,則移除關鍵字 deferred

dart
import 'a.dart' as a;

void f() {
  a.Library();
}

如果需要延遲匯入匯入的程式庫,並且您需要參考匯入的函數,則重新命名匯入的程式庫中的函數

dart
void populateLibrary(Library library) {}

class Library {}

如果需要延遲匯入匯入的程式庫,並且您不需要參考匯入的函數,則新增 hide 子句

dart
import 'a.dart' deferred as a hide loadLibrary;

void f() {
  a.Library();
}

匯入內部程式庫

#

程式庫 '{0}' 是內部程式庫,無法匯入。

描述

#

當分析器找到其 dart: URI 參考內部程式庫的匯入時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 _interceptors 是一個內部程式庫

dart
import 'dart:_interceptors';

常見修正方式

#

移除匯入指令。

將舊版程式庫匯入至空值安全程式庫

#

程式庫 '{0}' 是舊版程式庫,不應匯入到 null safe 程式庫中。

描述

#

當 null safe 程式庫匯入非 null safe 程式庫時,分析器會產生此診斷訊息。

範例

#

給定一個包含以下內容的檔案 a.dart

dart
// @dart = 2.9

class A {}

以下程式碼會產生此診斷訊息,因為 null safe 程式庫正在匯入非 null safe 程式庫

dart
import 'a.dart';

A? f() => null;

常見修正方式

#

如果您可以將匯入的程式庫遷移到 null safe,則遷移它並更新或移除遷移程式庫的語言版本。

如果您無法遷移匯入的程式庫,則匯入程式庫需要具有在 2.12 之前的語言版本,當時預設啟用 null safety。

匯入非程式庫

#

匯入的程式庫 '{0}' 不能有 part-of 指令。

描述

#

part 檔案 匯入到程式庫中時,分析器會產生此診斷訊息。

範例

#

給定一個名為 part.dartpart 檔案,其中包含以下內容

dart
part of lib;

以下程式碼會產生此診斷訊息,因為匯入的檔案不能有 part-of 指令

dart
library lib;

import 'part.dart';

常見修正方式

#

匯入包含部分檔案的程式庫,而不是部分檔案本身。

不一致的繼承

#

超介面對於 '{0}' 沒有有效的覆寫:{1}。

描述

#

當一個類別繼承了成員的兩個或多個衝突簽名,且沒有提供滿足所有繼承簽名的實作時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 CA 繼承了 m 的宣告,而該實作與從 B 繼承的 m 簽名不一致。

dart
class A {
  void m({int? a}) {}
}

class B {
  void m({int? b}) {}
}

class C extends A implements B {
}

常見修正方式

#

新增一個方法的實作,以滿足所有繼承的簽名。

dart
class A {
  void m({int? a}) {}
}

class B {
  void m({int? b}) {}
}

class C extends A implements B {
  void m({int? a, int? b}) {}
}

不一致的語言版本覆寫

#

部分檔案必須與程式庫具有完全相同的語言版本覆寫。

描述

#

部分檔案的語言版本覆寫註解指定的語言版本,與部分檔案所屬程式庫使用的語言版本不同時,分析器會產生此診斷訊息。

範例

#

假設有一個名為 part.dart部分檔案,其中包含以下內容:

dart
// @dart = 2.14
part of 'test.dart';

以下程式碼會產生此診斷訊息,因為程式庫的部分檔案必須與定義編譯單元具有相同的語言版本。

dart
// @dart = 2.15
part 'part.dart';

常見修正方式

#

部分檔案中移除語言版本覆寫,使其隱含地使用與定義編譯單元相同的版本。

dart
part of 'test.dart';

如有必要,調整定義編譯單元中的語言版本覆寫,使其適用於部分檔案中的程式碼,或者將部分檔案中的程式碼遷移為與新的語言版本一致。

不一致的模式變數邏輯或

#

變數 '{0}' 在邏輯或模式的這個分支中具有不同的類型和/或最終性。

描述

#

當在邏輯或模式的所有分支上宣告的模式變數,在每個分支上沒有相同的類型時,分析器會產生此診斷訊息。當變數在不同分支上具有不同的最終性時,也會產生此訊息。在邏輯或模式的多個分支上宣告的模式變數,在每個分支中都必須具有相同的類型和最終性,以便在受邏輯或模式保護的程式碼中可以知道變數的類型和最終性。

範例

#

以下程式碼會產生此診斷訊息,因為變數 a 在一個分支中定義為 int,而在另一個分支中定義為 double

dart
void f(Object? x) {
  if (x case (int a) || (double a)) {
    print(a);
  }
}

以下程式碼會產生此診斷訊息,因為變數 a 在第一個分支中是 final,而在第二個分支中不是 final

dart
void f(Object? x) {
  if (x case (final int a) || (int a)) {
    print(a);
  }
}

常見修正方式

#

如果變數的最終性不同,請決定它應該是 final 或非 final,並使情況保持一致。

dart
void f(Object? x) {
  if (x case (int a) || (int a)) {
    print(a);
  }
}

如果變數的類型不同,且類型對於要匹配的條件並非至關重要,則請確保變數在兩個分支上都具有相同的類型。

dart
void f(Object? x) {
  if (x case (num a) || (num a)) {
    print(a);
  }
}

如果變數的類型不同,且類型對於要匹配的條件至關重要,則請考慮將條件分解為多個 if 語句或 case 子句。

dart
void f(Object? x) {
  if (x case int a) {
    print(a);
  } else if (x case double a) {
    print(a);
  }
}

不存在欄位的初始化器

#

'{0}' 不是封閉類別中的欄位。

描述

#

當建構子初始化一個未在包含該建構子的類別中宣告的欄位時,分析器會產生此診斷訊息。建構子無法初始化未宣告的欄位以及從超類別繼承的欄位。

範例

#

以下程式碼會產生此診斷訊息,因為初始化器正在初始化 x,但 x 不是類別中的欄位。

dart
class C {
  int? y;

  C() : x = 0;
}

常見修正方式

#

如果應該初始化不同的欄位,則將名稱更改為欄位的名稱。

dart
class C {
  int? y;

  C() : y = 0;
}

如果必須宣告欄位,則新增宣告。

dart
class C {
  int? x;
  int? y;

  C() : x = 0;
}

靜態欄位的初始化器

#

'{0}' 是封閉類別中的靜態欄位。在建構子中初始化的欄位不能是靜態的。

描述

#

當靜態欄位在建構子中使用初始化形式參數或初始化列表中的賦值進行初始化時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為靜態欄位 a 正在由初始化形式參數 this.a 初始化。

dart
class C {
  static int? a;
  C(this.a);
}

常見修正方式

#

如果欄位應該是實例欄位,則移除關鍵字 static

dart
class C {
  int? a;
  C(this.a);
}

如果您打算初始化實例欄位但輸入了錯誤的名稱,則更正要初始化的欄位的名稱。

dart
class C {
  static int? a;
  int? b;
  C(this.b);
}

如果您真的想要初始化靜態欄位,則將初始化移至建構子主體中。

dart
class C {
  static int? a;
  C(int? c) {
    a = c;
  }
}

不存在欄位的初始化形式參數

#

'{0}' 不是封閉類別中的欄位。

描述

#

當在未宣告要初始化的欄位的類別中的建構子中找到初始化形式參數時,分析器會產生此診斷訊息。建構子無法初始化未宣告的欄位以及從超類別繼承的欄位。

範例

#

以下程式碼會產生此診斷訊息,因為未定義欄位 x

dart
class C {
  int? y;

  C(this.x);
}

常見修正方式

#

如果欄位名稱錯誤,則將其更改為現有欄位的名稱。

dart
class C {
  int? y;

  C(this.y);
}

如果欄位名稱正確但尚未定義,則宣告該欄位。

dart
class C {
  int? x;
  int? y;

  C(this.x);
}

如果需要參數但不應初始化欄位,則將其轉換為一般參數並使用它。

dart
class C {
  int y;

  C(int x) : y = x * 2;
}

如果不需要參數,則移除它。

dart
class C {
  int? y;

  C();
}

實例存取靜態成員

#

無法透過實例存取靜態 {1} '{0}'。

描述

#

當使用存取運算子透過類別的實例存取靜態成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 zero 是一個靜態欄位,但它被當作實例欄位存取。

dart
void f(C c) {
  c.zero;
}

class C {
  static int zero = 0;
}

常見修正方式

#

使用類別來存取靜態成員。

dart
void f(C c) {
  C.zero;
}

class C {
  static int zero = 0;
}

來自_factory的實例成員存取

#

無法從工廠建構子存取實例成員。

描述

#

當工廠建構子包含對實例成員的非限定引用時,分析器會產生此診斷訊息。在生成式建構子中,類別的實例在建構子的主體執行之前被建立和初始化,因此實例可以綁定到 this 並像在實例方法中一樣存取。但是,在工廠建構子中,實例在執行主體之前不會被建立,因此無法使用 this 來引用它。

範例

#

以下程式碼會產生此診斷訊息,因為 x 在工廠建構子中不在作用域內。

dart
class C {
  int x;
  factory C() {
    return C._(x);
  }
  C._(this.x);
}

常見修正方式

#

重寫程式碼,使其不引用實例成員。

dart
class C {
  int x;
  factory C() {
    return C._(0);
  }
  C._(this.x);
}

來自靜態的實例成員存取

#

無法從靜態方法存取實例成員。

描述

#

當靜態方法包含對實例成員的非限定引用時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為實例欄位 x 正在靜態方法中被引用。

dart
class C {
  int x = 0;

  static int m() {
    return x;
  }
}

常見修正方式

#

如果方法必須引用實例成員,則它不能是靜態的,因此移除關鍵字。

dart
class C {
  int x = 0;

  int m() {
    return x;
  }
}

如果方法不能設為實例方法,則新增一個參數,以便可以傳入類別的實例。

dart
class C {
  int x = 0;

  static int m(C c) {
    return c.x;
  }
}

具現化抽象類別

#

抽象類別無法被實例化。

描述

#

當分析器找到建構子調用,且該建構子在抽象類別中宣告時,會產生此診斷訊息。即使您無法建立抽象類別的實例,抽象類別也可以宣告可以被子類別調用的建構子。

範例

#

以下程式碼會產生此診斷訊息,因為 C 是一個抽象類別。

dart
abstract class C {}

var c = new C();

常見修正方式

#

如果有可以使用的抽象類別的具體子類別,則建立具體子類別的實例。

具現化列舉

#

列舉無法被實例化。

描述

#

當列舉被實例化時,分析器會產生此診斷訊息。透過調用建構子來建立列舉的實例是無效的;只有在列舉宣告中命名的實例才能存在。

範例

#

以下程式碼會產生此診斷訊息,因為列舉 E 正在被實例化。

dart
// @dart = 2.16
enum E {a}

var e = E();

常見修正方式

#

如果您打算使用列舉的實例,則引用在列舉中定義的常數之一。

dart
// @dart = 2.16
enum E {a}

var e = E.a;

如果您打算使用類別的實例,則使用該類別的名稱來代替列舉的名稱。

類型別名展開為類型參數

#

展開為型別參數的型別別名無法被實例化。

描述

#

當找到建構子調用,且要實例化的型別是型別別名的型別參數之一的型別別名時,分析器會產生此診斷訊息。這是不允許的,因為型別參數的值是一個型別而不是一個類別。

範例

#

以下程式碼會產生此診斷訊息,因為它建立 A 的實例,即使 A 是一個定義為等效於型別參數的型別別名。

dart
typedef A<T> = T;

void f() {
  const A<int>();
}

常見修正方式

#

使用類別名稱或定義為類別的型別別名,而不是定義為型別參數的型別別名。

dart
typedef A<T> = C<T>;

void f() {
  const A<int>();
}

class C<T> {
  const C();
}

整數字面值作為雙精度浮點數不精確

#

整數文字正在用作 double,但無法表示為 64 位元 double 而不會溢位或損失精確度:'{0}'。

描述

#

當整數文字被隱含地轉換為 double,但無法表示為 64 位元 double 而不會溢位或損失精確度時,分析器會產生此診斷訊息。如果上下文需要 double 類型,則整數文字會隱含地轉換為 double。

範例

#

以下程式碼會產生此診斷訊息,因為整數值 9223372036854775807 無法精確地表示為 double。

dart
double x = 9223372036854775807;

常見修正方式

#

如果您需要使用精確值,則使用類別 BigInt 來表示該值。

dart
var x = BigInt.parse('9223372036854775807');

如果您需要使用 double,則將值更改為可以精確表示的值。

dart
double x = 9223372036854775808;

整數字面值超出範圍

#

整數文字 {0} 無法以 64 位元表示。

描述

#

當整數文字的值太大(正數)或太小(負數)而無法以 64 位元字組表示時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為該值無法以 64 位元表示。

dart
var x = 9223372036854775810;

常見修正方式

#

如果您需要表示目前的值,則將其包裝在類別 BigInt 的實例中。

dart
var x = BigInt.parse('9223372036854775810');

無效的註解

#

註解必須是常數變數引用或常數建構子調用。

描述

#

當找到一個註解,它正在使用既不是標記為 const 的變數,也不是 const 建構子的調用時,分析器會產生此診斷訊息。

Getter 不能用作註解。

範例

#

以下程式碼會產生此診斷訊息,因為變數 v 不是 const 變數。

dart
var v = 0;

@v
void f() {
}

以下程式碼會產生此診斷訊息,因為 f 不是變數。

dart
@f
void f() {
}

以下程式碼會產生此診斷訊息,因為 f 不是建構子。

dart
@f()
void f() {
}

以下程式碼會產生此診斷訊息,因為 g 是一個 getter。

dart
@g
int get g => 0;

常見修正方式

#

如果註解正在引用一個不是 const 建構子的變數,則將關鍵字 const 新增到變數的宣告中。

dart
const v = 0;

@v
void f() {
}

如果註解沒有引用變數,則移除它。

dart
int v = 0;

void f() {
}

來自延遲載入程式庫的無效註解常數值

#

來自延遲載入程式庫的常數值不能在註解中使用。

描述

#

當在註解的引數列表中引用了在作為延遲載入程式庫匯入的程式庫中定義的常數時,分析器會產生此診斷訊息。註解在編譯時評估,而來自延遲載入程式庫的值在編譯時不可用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

以下程式碼會產生此診斷訊息,因為常數 pi 正在註解的引數列表中被引用,即使定義它的程式庫正在作為延遲載入程式庫匯入。

dart
import 'dart:math' deferred as math;

class C {
  const C(double d);
}

@C(math.pi)
void f () {}

常見修正方式

#

如果您需要引用匯入的常數,則移除 deferred 關鍵字。

dart
import 'dart:math' as math;

class C {
  const C(double d);
}

@C(math.pi)
void f () {}

如果匯入必須是延遲的,並且有另一個適當的常數,則使用該常數代替來自延遲載入程式庫的常數。

來自延遲載入程式庫的無效註解

#

來自延遲載入程式庫的常數值不能用作註解。

描述

#

當來自使用延遲匯入匯入的程式庫的常數被用作註解時,分析器會產生此診斷訊息。註解在編譯時評估,而來自延遲載入程式庫的常數在編譯時不可用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

以下程式碼會產生此診斷訊息,因為當程式庫 dart:mathdeferred 形式匯入時,常數 pi 被用作註解。

dart
import 'dart:math' deferred as math;

@math.pi
void f() {}

常見修正方式

#

如果您需要將常數作為註解引用,則從匯入中移除關鍵字 deferred

dart
import 'dart:math' as math;

@math.pi
void f() {}

如果您可以使用不同的常數作為註解,則將註解替換為不同的常數。

dart
@deprecated
void f() {}

無效的註解目標

#

註解 '{0}' 只能在 {1} 上使用。

描述

#

當註解應用於它不支持的宣告種類時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 optionalTypeArgs 註解未定義為對頂層變數有效。

dart
import 'package:meta/meta.dart';

@optionalTypeArgs
int x = 0;

常見修正方式

#

從宣告中移除註解。

無效的賦值

#

類型為 '{0}' 的值無法指派給類型為 '{1}' 的變數。

描述

#

當指派給變數的表達式的靜態類型無法指派給變數的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為初始化器 (int) 的類型無法指派給變數 (String) 的類型。

dart
int i = 0;
String s = i;

常見修正方式

#

如果被指派的值在運行時始終可指派,即使靜態類型沒有反映這一點,則新增明確的類型轉換。

否則,更改被指派的值,使其具有預期的類型。在先前的範例中,這可能看起來像:

dart
int i = 0;
String s = i.toString();

如果您無法更改值,則更改變數的類型,使其與被指派的值的類型相容。

dart
int i = 0;
int s = i;

無效的相依性

#

可發布的套件不能有 '{0}' 依賴項。

描述

#

當可發布的套件在其 pubspec.yaml 檔案的 dependencies 列表中包含一個不是 pub 託管依賴項的套件時,分析器會產生此診斷訊息。

要了解有關不同類型依賴項來源的更多資訊,請查看 套件依賴項

範例

#

以下程式碼會產生此診斷訊息,因為對套件 transmogrify 的依賴項不是 pub 託管依賴項。

yaml
name: example
dependencies:
  transmogrify:
    path: ../transmogrify

常見修正方式

#

如果您想將套件發布到 pub.dev,則將依賴項更改為在 pub.dev 上發布的託管套件。

如果套件不打算發布到 pub.dev,則在其 pubspec.yaml 檔案中新增 publish_to: none 條目,以將其標記為不打算發布。

yaml
name: example
publish_to: none
dependencies:
  transmogrify:
    path: ../transmogrify

無效的例外值

#

當函數的回傳類型為 'void'、'Handle' 或 'Pointer' 時,方法 {0} 不能有例外回傳值(第二個引數)。

描述

#

當方法 Pointer.fromFunctionNativeCallable.isolateLocal 的調用具有第二個引數(例外回傳值),且從調用回傳的類型為 voidHandlePointer 時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為當 f 的回傳類型為 void 時,提供了第二個引數。

dart
import 'dart:ffi';

typedef T = Void Function(Int8);

void f(int i) {}

void g() {
  Pointer.fromFunction<T>(f, 42);
}

常見修正方式

#

移除例外值。

dart
import 'dart:ffi';

typedef T = Void Function(Int8);

void f(int i) {}

void g() {
  Pointer.fromFunction<T>(f);
}

無效的內部元素匯出

#

成員 '{0}' 不能作為套件公有 API 的一部分匯出。

描述

#

公有程式庫匯出一個標記有 internal 註解的宣告時,分析器會產生此診斷訊息。

範例

#

假設在 src 目錄中有一個檔案 a.dart,其中包含:

dart
import 'package:meta/meta.dart';

@internal class One {}

當在公有程式庫中找到以下程式碼時,會產生此診斷訊息,因為 export 指令正在匯出一個僅供內部使用的名稱。

dart
export 'src/a.dart';

常見修正方式

#

如果需要匯出,則新增一個 hide 子句以隱藏內部名稱。

dart
export 'src/a.dart' hide One;

如果不需要匯出,則移除它。

間接無效的內部元素匯出

#

成員 '{0}' 不能作為套件公有 API 的一部分匯出,但作為 '{1}' 簽名的一部分間接匯出。

描述

#

公有程式庫匯出一個頂層函數,其回傳類型或至少一個參數類型標記有 internal 註解時,分析器會產生此診斷訊息。

範例

#

假設在 src 目錄中有一個檔案 a.dart,其中包含以下內容:

dart
import 'package:meta/meta.dart';

@internal
typedef IntFunction = int Function();

int f(IntFunction g) => g();

以下程式碼會產生此診斷訊息,因為函數 f 具有類型為 IntFunction 的參數,而 IntFunction 僅供內部使用。

dart
export 'src/a.dart' show f;

常見修正方式

#

如果函數必須是公有的,則使函數簽名中的所有類型都成為公有類型。

如果函數不需要匯出,則停止匯出它,可以透過從 show 子句中移除它、將其新增到 hide 子句中,或移除匯出來實現。

無效的擴充功能引數計數

#

擴充功能覆寫必須恰好有一個引數:擴充方法中 'this' 的值。

描述

#

當擴充功能覆寫沒有恰好一個引數時,分析器會產生此診斷訊息。該引數是用於計算擴充方法中 this 值的表達式,因此必須有一個引數。

範例

#

以下程式碼會產生此診斷訊息,因為沒有引數。

dart
extension E on String {
  String join(String other) => '$this $other';
}

void f() {
  E().join('b');
}

並且,以下程式碼會產生此診斷訊息,因為有多個引數。

dart
extension E on String {
  String join(String other) => '$this $other';
}

void f() {
  E('a', 'b').join('c');
}

常見修正方式

#

為擴充功能覆寫提供一個引數。

dart
extension E on String {
  String join(String other) => '$this $other';
}

void f() {
  E('a').join('b');
}

無效的_factory_方法宣告

#

工廠方法 '{0}' 必須具有回傳類型。

描述

#

當標記有 factory 註解的方法具有 void 的回傳類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為方法 createC 標記有 factory 註解,但沒有回傳任何值。

dart
import 'package:meta/meta.dart';

class Factory {
  @factory
  void createC() {}
}

class C {}

常見修正方式

#

將回傳類型更改為 void 以外的類型。

dart
import 'package:meta/meta.dart';

class Factory {
  @factory
  C createC() => C();
}

class C {}

無效的_factory_方法實作

#

工廠方法 '{0}' 沒有回傳新分配的物件。

描述

#

當標記有 factory 註解的方法沒有回傳新分配的物件時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為方法 createC 回傳欄位的值,而不是新建立的 C 實例。

dart
import 'package:meta/meta.dart';

class Factory {
  C c = C();

  @factory
  C createC() => c;
}

class C {}

常見修正方式

#

將方法更改為回傳新建立的回傳類型實例。

dart
import 'package:meta/meta.dart';

class Factory {
  @factory
  C createC() => C();
}

class C {}

無效的_factory_名稱不是類別

#

工廠建構子的名稱必須與直接封閉類別的名稱相同。

描述

#

當工廠建構子的名稱與周圍類別的名稱不同時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為工廠建構子的名稱 (A) 與周圍類別 (C) 的名稱不同。

dart
class A {}

class C {
  factory A() => throw 0;
}

常見修正方式

#

如果工廠回傳周圍類別的實例,並且您打算使其成為未命名的工廠建構子,則重新命名工廠。

dart
class A {}

class C {
  factory C() => throw 0;
}

如果工廠回傳周圍類別的實例,並且您打算使其成為命名的工廠建構子,則在工廠建構子的名稱前加上周圍類別的名稱。

dart
class A {}

class C {
  factory C.a() => throw 0;
}

如果工廠回傳不同類別的實例,則將工廠移至該類別。

dart
class A {
  factory A() => throw 0;
}

class C {}

如果工廠回傳不同類別的實例,但您無法修改該類別或不想移動工廠,則將其轉換為靜態方法。

dart
class A {}

class C {
  static A a() => throw 0;
}

無效的欄位名稱

#

當整數是位置欄位的索引時,記錄欄位名稱不能是錢字符號後跟一個整數。

記錄欄位名稱不能是私有的。

記錄欄位名稱不能與 'Object' 中的成員相同。

描述

#

當記錄文字或記錄類型註解具有一個欄位,其名稱無效時,分析器會產生此診斷訊息。如果名稱是以下情況,則無效:

  • 私有的 (以 _ 開頭)
  • 與在 Object 上定義的成員之一相同
  • 與位置欄位的名稱相同(如果欄位是具有指定名稱的位置欄位,則會例外)

範例

#

以下程式碼會產生此診斷訊息,因為記錄文字具有一個名為 toString 的欄位,它是 Object 上定義的方法。

dart
var r = (a: 1, toString: 4);

以下程式碼會產生此診斷訊息,因為記錄類型註解具有一個名為 hashCode 的欄位,它是 Object 上定義的 getter。

dart
void f(({int a, int hashCode}) r) {}

以下程式碼會產生此診斷訊息,因為記錄文字具有一個私有欄位,名為 _a

dart
var r = (_a: 1, b: 2);

以下程式碼會產生此診斷訊息,因為記錄類型註解具有一個私有欄位,名為 _a

dart
void f(({int _a, int b}) r) {}

以下程式碼會產生此診斷訊息,因為記錄文字具有一個名為 $1 的欄位,這也是另一個位置參數的名稱。

dart
var r = (2, $1: 1);

以下程式碼會產生此診斷訊息,因為記錄類型註解具有一個名為 $1 的欄位,這也是另一個位置參數的名稱。

dart
void f((int, String, {int $1}) r) {}

常見修正方式

#

重新命名欄位。

dart
var r = (a: 1, d: 4);

struct中無效的欄位類型

#

結構類別中的欄位不能具有類型 '{0}'。它們只能宣告為 'int'、'double'、'Array'、'Pointer' 或 'Struct' 或 'Union' 的子類型。

描述

#

Struct 的子類別中的欄位具有類型,而不是 intdoubleArrayPointerStructUnion 的子類型時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 str 具有類型 String,這不是 Struct 子類別中欄位的允許類型之一。

dart
import 'dart:ffi';

final class C extends Struct {
  external String s;

  @Int32()
  external int i;
}

常見修正方式

#

對欄位使用允許的類型之一。

dart
import 'dart:ffi';
import 'package:ffi/ffi.dart';

final class C extends Struct {
  external Pointer<Utf8> s;

  @Int32()
  external int i;
}

無效的實作覆寫

#

'{1}.{0}' ('{2}') 不是 '{3}.{0}' ('{4}') 的有效具體實作。

Setter '{1}.{0}' ('{2}') 不是 '{3}.{0}' ('{4}') 的有效具體實作。

描述

#

當以下所有條件都成立時,分析器會產生此診斷訊息:

  • 一個類別定義了一個抽象成員。
  • 在超類別中存在該成員的具體實作。
  • 具體實作不是抽象方法的有效實作。

具體實作可能是無效的,因為回傳類型、方法參數的類型或型別參數不相容。

範例

#

以下程式碼會產生此診斷訊息,因為方法 A.add 具有類型為 int 的參數,而覆寫方法 B.add 具有對應的類型為 num 的參數。

dart
class A {
  int add(int a) => a;
}
class B extends A {
  int add(num a);
}

這是一個問題,因為在像以下這樣的 B.add 調用中:

dart
void f(B b) {
  b.add(3.4);
}

B.add 期望能夠接受,例如,一個 double,但是當方法 A.add 被執行時(因為它是 add 的唯一具體實作),將會拋出運行時異常,因為 double 無法指派給類型為 int 的參數。

常見修正方式

#

如果子類別中的方法可以符合超類別中的實作,則更改子類別中的宣告(如果相同,則移除它)。

dart
class A {
  int add(int a) => a;
}
class B	extends A {
  int add(int a);
}

如果可以將超類別中的方法廣義化,使其成為子類別中方法的有效實作,則更改超類別方法。

dart
class A {
  int add(num a) => a.floor();
}
class B	extends A {
  int add(num a);
}

如果超類別中的方法和子類別中的方法都無法更改,則在子類別中提供方法的具體實作。

dart
class A {
  int add(int a) => a;
}
class B	extends A {
  int add(num a) => a.floor();
}

無效的內嵌函式類型

#

內聯函數類型不能用於泛型函數類型中的參數。

描述

#

當泛型函數類型具有一個函數值參數,該參數是使用較舊的內聯函數類型語法編寫時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為在用於定義 F 的泛型函數類型中,參數 f 使用了內聯函數類型語法。

dart
typedef F = int Function(int f(String s));

常見修正方式

#

對參數的類型使用泛型函數語法。

dart
typedef F = int Function(int Function(String));

無效的內部註解

#

只有套件私有 API 中的公有元素才能標記為內部。

描述

#

當宣告標記有 internal 註解,且該宣告位於公有程式庫中或具有私有名稱時,分析器會產生此診斷訊息。

範例

#

當在公有程式庫中時,以下程式碼會產生此診斷訊息,因為 internal 註解不能應用於公有程式庫中的宣告。

dart
import 'package:meta/meta.dart';

@internal
class C {}

無論是在公有程式庫還是內部程式庫中,以下程式碼都會產生此診斷訊息,因為 internal 註解不能應用於具有私有名稱的宣告。

dart
import 'package:meta/meta.dart';

@internal
class _C {}

void f(_C c) {}

常見修正方式

#

如果宣告具有私有名稱,則移除註解。

dart
class _C {}

void f(_C c) {}

如果宣告具有公有名稱並且打算在套件內部使用,則將帶註解的宣告移至內部程式庫(換句話說,src 目錄內的程式庫)。

否則,移除註解的使用。

dart
class C {}

無效的語言版本覆寫

#

Dart 語言版本覆寫註解後面不能跟隨任何非空白字元。

Dart 語言版本覆寫註解必須使用版本號碼指定,例如 '=' 字元後的 '2.0'。

Dart 語言版本覆寫註解必須使用 '=' 字元指定。

Dart 語言版本覆寫註解必須使用正好兩個斜線指定。

Dart 語言版本覆寫註解必須使用全小寫的單字 'dart' 指定。

Dart 語言版本覆寫號碼不能以字母作為前綴。

Dart 語言版本覆寫號碼必須以 '@dart' 開頭。

語言版本覆寫不能指定大於最新已知語言版本的版本:{0}.{1}。

語言版本覆寫必須在任何宣告或指令之前指定。

描述

#

當一個看起來像是嘗試指定語言版本覆寫的註解不符合此類註解的要求時,分析器會產生此診斷訊息。有關更多資訊,請參閱 每個程式庫的語言版本選擇

範例

#

以下程式碼會產生此診斷訊息,因為單字 dart 在此類註解中必須是小寫,並且因為在單字 dart 和版本號碼之間沒有等號。

dart
// @Dart 2.13

常見修正方式

#

如果註解打算作為語言版本覆寫,則更改註解以遵循正確的格式。

dart
// @dart = 2.13

無效的字面值註解

#

只有常數建構子才能具有 @literal 註解。

描述

#

literal 註解應用於常數建構子以外的任何事物時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息,因為建構子不是 const 建構子

dart
import 'package:meta/meta.dart';

class C {
  @literal
  C();
}

以下程式碼會產生此診斷訊息,因為 x 不是建構子。

dart
import 'package:meta/meta.dart';

@literal
var x;

常見修正方式

#

如果註解在建構子上,且建構子應盡可能始終使用 const 調用,則使用 const 關鍵字標記建構子。

dart
import 'package:meta/meta.dart';

class C {
  @literal
  const C();
}

如果建構子不能標記為 const,則移除註解。

如果註解在建構子以外的任何事物上,則移除註解。

dart
var x;

建構子上無效的修飾詞

#

修飾詞 '{0}' 不能應用於建構子的主體。

描述

#

當建構子的主體以以下修飾詞之一作為前綴時,分析器會產生此診斷訊息:asyncasync*sync*。建構子主體必須是同步的。

範例

#

以下程式碼會產生此診斷訊息,因為 C 的建構子的主體被標記為 async

dart
class C {
  C() async {}
}

常見修正方式

#

如果建構子可以是同步的,則移除修飾詞。

dart
class C {
  C();
}

如果建構子不能是同步的,則使用靜態方法來建立實例。

dart
class C {
  C();
  static Future<C> c() async {
    return C();
  }
}

setter上無效的修飾詞

#

Setter 不能使用 'async'、'async*' 或 'sync*'。

描述

#

當 setter 的主體以以下修飾詞之一作為前綴時,分析器會產生此診斷訊息:asyncasync*sync*。Setter 主體必須是同步的。

範例

#

以下程式碼產生此診斷訊息,因為 setter x 的主體被標記為 async

dart
class C {
  set x(int i) async {}
}

常見修正方式

#

如果 setter 可以是同步的,請移除修飾詞

dart
class C {
  set x(int i) {}
}

如果 setter 無法是同步的,請改用方法來設定值

dart
class C {
  void x(int i) async {}
}

無效的非虛擬註解

#

@nonVirtual 註解只能套用至具體的實例成員。

描述

#

當在類別、Mixin 或列舉的成員以外的宣告中,或是成員不是具體的實例成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為註解是在類別宣告上,而不是在類別內部的成員上

dart
import 'package:meta/meta.dart';

@nonVirtual
class C {}

以下程式碼產生此診斷訊息,因為方法 m 是一個抽象方法

dart
import 'package:meta/meta.dart';

abstract class C {
  @nonVirtual
  void m();
}

以下程式碼產生此診斷訊息,因為方法 m 是一個靜態方法

dart
import 'package:meta/meta.dart';

abstract class C {
  @nonVirtual
  static void m() {}
}

常見修正方式

#

如果宣告不是類別、Mixin 或列舉的成員,請移除註解

dart
class C {}

如果成員的目的是成為具體的實例成員,請使其成為具體的實例成員

dart
import 'package:meta/meta.dart';

abstract class C {
  @nonVirtual
  void m() {}
}

如果成員的意圖不是成為具體的實例成員,請移除註解

dart
abstract class C {
  static void m() {}
}

無效的_null_感知運算子

#

元素不能為 null,因此 null 感知運算子 '?' 是不必要的。

Map 條目的鍵不能為 null,因此 null 感知運算子 '?' 是不必要的。

Map 條目的值不能為 null,因此 null 感知運算子 '?' 是不必要的。

由於短路求值,接收器不能為 'null',因此不能使用 null 感知運算子 '{0}'。

接收器不能為 null,因此 null 感知運算子 '{0}' 是不必要的。

描述

#

當在已知為不可為 null 的接收器上使用 null 感知運算子 (?.?..?[?..[...?) 時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 s 不能為 null

dart
int? getLength(String s) {
  return s?.length;
}

以下程式碼產生此診斷訊息,因為 a 不能為 null

dart
var a = [];
var b = [...?a];

以下程式碼產生此診斷訊息,因為 s?.length 不能傳回 null

dart
void f(String? s) {
  s?.length?.isEven;
}

s?.length 不能傳回 null 的原因是,如果 snull,則在 s 之後的 null 感知運算子會短路求值 lengthisEven。換句話說,如果 snull,則 lengthisEven 都將不會被調用;如果 s 為非 null,則 length 不能傳回 null 值。無論如何,isEven 都不能在 null 值上調用,因此 null 感知運算子是不必要的。請參閱 Understanding null safety 以取得更多詳細資訊。

以下程式碼產生此診斷訊息,因為 s 不能為 null

dart
void f(Object? o) {
  var s = o as String;
  s?.length;
}

儘管 o 可以為 null,但 s 不能為 null 的原因是強制轉換為 String,這是一個不可為 null 的類型。如果 o 的值為 null,則強制轉換將會失敗,並且 length 的調用將不會發生。

以下程式碼產生此診斷訊息,因為 s 不能為 null

dart
List<String> makeSingletonList(String s) {
  return <String>[?s];
}

常見修正方式

#

將 null 感知運算子替換為非 null 感知等效項;例如,將 ?. 變更為 .

dart
int getLength(String s) {
  return s.length;
}

(請注意,傳回類型也已變更為不可為 null,這在某些情況下可能不合適。)

無效的覆寫

#

'{1}.{0}' ('{2}') 不是 '{3}.{0}' ('{4}') 的有效覆寫。

Setter '{1}.{0}' ('{2}') 不是 '{3}.{0}' ('{4}') 的有效覆寫。

描述

#

當在類別中找到成員覆寫了超類型的成員,且覆寫無效時,分析器會產生此診斷訊息。如果以下所有條件都成立,則覆寫有效

  • 它允許被覆寫成員所允許的所有引數。
  • 它不要求任何被覆寫成員未要求的引數。
  • 被覆寫成員的每個參數的類型都可指派給覆寫的對應參數。
  • 覆寫的傳回類型可指派給被覆寫成員的傳回類型。

範例

#

以下程式碼產生此診斷訊息,因為參數 s (String) 的類型不可指派給參數 i (int) 的類型

dart
class A {
  void m(int i) {}
}

class B extends A {
  void m(String s) {}
}

常見修正方式

#

如果無效方法的目的是覆寫超類別中的方法,請變更它以符合規範

dart
class A {
  void m(int i) {}
}

class B extends A {
  void m(int i) {}
}

如果它的目的不是覆寫超類別中的方法,請重新命名它

dart
class A {
  void m(int i) {}
}

class B extends A {
  void m2(String s) {}
}

無效的非虛擬成員覆寫

#

成員 '{0}' 在 '{1}' 中宣告為 non-virtual,且無法在子類別中覆寫。

描述

#

當類別、Mixin 或列舉的成員覆寫了具有 @nonVirtual 註解的成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 B 中的方法 m 覆寫了 A 中的方法 m,而 A 中的方法 m 使用了 @nonVirtual 註解

dart
import 'package:meta/meta.dart';

class A {
  @nonVirtual
  void m() {}
}

class B extends A {
  @override
  void m() {}
}

常見修正方式

#

如果超類別中方法的註解是正確的 (超類別中的方法不應被覆寫),則移除或重新命名覆寫方法

dart
import 'package:meta/meta.dart';

class A {
  @nonVirtual
  void m() {}
}

class B extends A {}

如果超類別中的方法旨在被覆寫,則移除 @nonVirtual 註解

dart
class A {
  void m() {}
}

class B extends A {
  @override
  void m() {}
}

共用_case_範圍中無效的模式變數

#

變數 '{0}' 在共用此主體的所有情況下,不具有相同的類型和/或最終性。

變數 '{0}' 在某些情況下可用,但在共用此主體的所有情況下並非都可用。

變數 '{0}' 不可用,因為存在標籤或 'default' case。

描述

#

當 switch 陳述式中的多個 case 子句共用一個主體,且至少其中一個子句宣告了一個在共用陳述式中被引用的變數,但該變數並非在所有 case 子句中都宣告,或是在宣告方式上不一致時,分析器會產生此診斷訊息。

如果變數未在所有 case 子句中宣告,則如果未宣告變數的子句是符合且執行主體的子句之一,則它將沒有值。這包括其中一個 case 子句是 default 子句的情況。

如果變數的宣告方式不一致,在某些情況下是 final 而在其他情況下不是 final,或者在不同情況下具有不同的類型,則變數的類型或最終性的語意應為何是未定義的。

範例

#

以下程式碼產生此診斷訊息,因為變數 a 僅在其中一個 case 子句中宣告,如果在第二個子句符合 x 時,將沒有值

dart
void f(Object? x) {
  switch (x) {
    case int a when a > 0:
    case 0:
      a;
  }
}

以下程式碼產生此診斷訊息,因為變數 a 未在 default 子句中宣告,如果在沒有其他子句符合 x 的情況下執行主體,將沒有值

dart
void f(Object? x) {
  switch (x) {
    case int a when a > 0:
    default:
      a;
  }
}

以下程式碼產生此診斷訊息,因為如果在不同的 case 群組導致控制權在標籤處繼續時,變數 a 將沒有值

dart
void f(Object? x) {
  switch (x) {
    someLabel:
    case int a when a > 0:
      a;
    case int b when b < 0:
      continue someLabel;
  }
}

以下程式碼產生此診斷訊息,因為變數 a 雖然在所有 case 子句中都已指派值,但在每個子句中都不具有相同的關聯類型

dart
void f(Object? x) {
  switch (x) {
    case int a when a < 0:
    case num a when a > 0:
      a;
  }
}

以下程式碼產生此診斷訊息,因為變數 a 在第一個 case 子句中是 final,但在第二個 case 子句中不是 final

dart
void f(Object? x) {
  switch (x) {
    case final int a when a < 0:
    case int a when a > 0:
      a;
  }
}

常見修正方式

#

如果變數未在所有 case 中宣告,且您需要在陳述式中引用它,則在其他 case 中宣告它

dart
void f(Object? x) {
  switch (x) {
    case int a when a > 0:
    case int a when a == 0:
      a;
  }
}

如果變數未在所有 case 中宣告,且您不需要在陳述式中引用它,則移除對它的引用,並從其他 case 中移除宣告

dart
void f(int x) {
  switch (x) {
    case > 0:
    case 0:
  }
}

如果變數的類型不同,請決定變數應具有的類型,並使 case 保持一致

dart
void f(Object? x) {
  switch (x) {
    case num a when a < 0:
    case num a when a > 0:
      a;
  }
}

如果變數的最終性不同,請決定它應該是 final 或非 final,並使情況保持一致。

dart
void f(Object? x) {
  switch (x) {
    case final int a when a < 0:
    case final int a when a > 0:
      a;
  }
}

無效的平台欄位

#

'platforms' 欄位必須是一個以平台作為鍵的 Map。

描述

#

當指定了頂層 platforms 欄位,但其值不是帶有鍵的 Map 時,分析器會產生此診斷訊息。若要深入了解如何指定套件支援的平台,請查看 平台宣告的文件

範例

#

以下 pubspec.yaml 產生此診斷訊息,因為 platforms 應為 Map。

yaml
name: example
platforms:
  - android
  - web
  - ios

常見修正方式

#

如果您可以依賴自動平台偵測,則省略頂層 platforms 欄位。

yaml
name: example

如果您需要手動指定支援平台的清單,則將 platforms 欄位寫為以平台名稱作為鍵的 Map。

yaml
name: example
platforms:
  android:
  web:
  ios:

對產生器列舉建構子的無效參考

#

產生器列舉建構子只能用作重新導向的目標。

描述

#

當在列舉中定義的產生器建構子用於建立其中一個列舉常數以外的任何地方,或用作來自相同列舉中另一個建構子的重新導向目標時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 E 的建構子正被用於在函數 f 中建立實例

dart
enum E {
  a(0);

  const E(int x);
}

E f() => const E(2);

常見修正方式

#

如果存在具有相同值的列舉值,或者如果您新增了這樣的常數,則直接引用該常數

dart
enum E {
  a(0), b(2);

  const E(int x);
}

E f() => E.b;

如果您需要使用建構子調用,則使用工廠建構子

dart
enum E {
  a(0);

  const E(int x);

  factory E.c(int x) => a;
}

E f() => E.c(2);

對_this的無效參考

#

無效的 'this' 表達式參考。

描述

#

當在實例方法或產生器建構子之外使用 this 時,分析器會產生此診斷訊息。保留字 this 僅在實例方法、產生器建構子或延遲實例欄位宣告的初始化器的上下文中定義。

範例

#

以下程式碼產生此診斷訊息,因為 v 是一個頂層變數

dart
C f() => this;

class C {}

常見修正方式

#

使用適當類型的變數來取代 this,必要時宣告它

dart
C f(C c) => c;

class C {}

catchError的無效傳回類型

#

類型為 '{0}' 的值無法由 'onError' 處理常式傳回,因為它必須可指派給 '{1}'。

傳回類型 '{0}' 不可指派給 '{1}',這是 'Future.catchError' 所要求的。

描述

#

Future.catchError 的調用具有一個引數,其傳回類型與 Future 實例傳回的類型不相容時,分析器會產生此診斷訊息。在執行階段,方法 catchError 嘗試從回呼傳回值作為 future 的結果,這會導致另一個例外被拋出。

範例

#

以下程式碼產生此診斷訊息,因為 future 被宣告為傳回 int,而 callback 被宣告為傳回 String,且 String 不是 int 的子類型

dart
void f(Future<int> future, String Function(dynamic, StackTrace) callback) {
  future.catchError(callback);
}

以下程式碼產生此診斷訊息,因為傳遞給 catchError 的閉包傳回 int,而 future 被宣告為傳回 String

dart
void f(Future<String> future) {
  future.catchError((error, stackTrace) => 3);
}

常見修正方式

#

如果 Future 的實例宣告正確,則變更回呼以符合

dart
void f(Future<int> future, int Function(dynamic, StackTrace) callback) {
  future.catchError(callback);
}

如果 Future 的實例宣告錯誤,則變更它以符合回呼

dart
void f(Future<String> future, String Function(dynamic, StackTrace) callback) {
  future.catchError(callback);
}

無效的_sealed_註解

#

@sealed 註解只能套用至類別。

描述

#

當類別宣告以外的宣告具有 @sealed 註解時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 @sealed 註解是在方法宣告上

dart
import 'package:meta/meta.dart';

class A {
  @sealed
  void m() {}
}

常見修正方式

#

移除註解

dart
class A {
  void m() {}
}

無效的_super_形式參數位置

#

Super 參數只能在非重新導向的產生器建構子中使用。

描述

#

當 super 參數用於非重新導向的產生器建構子以外的任何地方時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 super 參數 x 在重新導向的產生器建構子中

dart
class A {
  A(int x);
}

class B extends A {
  B.b(super.x) : this._();
  B._() : super(0);
}

以下程式碼產生此診斷訊息,因為 super 參數 x 不在產生器建構子中

dart
class A {
  A(int x);
}

class C extends A {
  factory C.c(super.x) => C._();
  C._() : super(0);
}

以下程式碼產生此診斷訊息,因為 super 參數 x 在方法中

dart
class A {
  A(int x);
}

class D extends A {
  D() : super(0);

  void m(super.x) {}
}

常見修正方式

#

如果包含 super 參數的函數可以變更為非重新導向的產生器建構子,請執行此操作

dart
class A {
  A(int x);
}

class B extends A {
  B.b(super.x);
}

如果包含 super 參數的函數無法變更為非重新導向的產生器建構子,則移除 super

dart
class A {
  A(int x);
}

class D extends A {
  D() : super(0);

  void m(int x) {}
}

const_字面值中無效的類型引數

#

常數 List 字面值不能在類型引數中使用類型參數,例如 '{0}'。

常數 Map 字面值不能在類型引數中使用類型參數,例如 '{0}'。

常數 Set 字面值不能在類型引數中使用類型參數,例如 '{0}'。

描述

#

當類型參數用於以 const 為前綴的 List、Map 或 Set 字面值中的類型引數時,分析器會產生此診斷訊息。這是不允許的,因為類型參數的值 (將在執行階段使用的實際類型) 在編譯時無法得知。

範例

#

以下程式碼產生此診斷訊息,因為類型參數 T 在建立常數 List 時被用作類型引數

dart
List<T> newList<T>() => const <T>[];

以下程式碼產生此診斷訊息,因為類型參數 T 在建立常數 Map 時被用作類型引數

dart
Map<String, T> newSet<T>() => const <String, T>{};

以下程式碼產生此診斷訊息,因為類型參數 T 在建立常數 Set 時被用作類型引數

dart
Set<T> newSet<T>() => const <T>{};

常見修正方式

#

如果將用於類型參數的類型可以在編譯時得知,則移除類型參數

dart
List<int> newList() => const <int>[];

如果將用於類型參數的類型在執行階段之前無法得知,則移除關鍵字 const

dart
List<T> newList<T>() => <T>[];

無效的_URI

#

無效的 URI 語法:'{0}'。

描述

#

當指令中的 URI 不符合有效 URI 的語法時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 '#' 不是有效的 URI

dart
import '#';

常見修正方式

#

將無效的 URI 替換為有效的 URI。

在擴充功能中無效地使用_covariant

#

Extension 中不能有修飾詞 '{0}'。

描述

#

當在 extension 內部宣告的成員在參數宣告中使用關鍵字 covariant 時,分析器會產生此診斷訊息。Extension 不是類別,也沒有子類別,因此該關鍵字沒有任何作用。

範例

#

以下程式碼產生此診斷訊息,因為 i 被標記為 covariant

dart
extension E on String {
  void a(covariant int i) {}
}

常見修正方式

#

移除 covariant 關鍵字

dart
extension E on String {
  void a(int i) {}
}

無效地使用內部成員

#

成員 '{0}' 只能在其套件內使用。

描述

#

當在包含宣告的套件外部找到對使用 internal 註解標記的宣告的引用時,分析器會產生此診斷訊息。

範例

#

假設一個套件 p 定義了一個程式庫,其中包含一個使用 internal 註解標記的宣告

dart
import 'package:meta/meta.dart';

@internal
class C {}

以下程式碼產生此診斷訊息,因為它正在引用類別 C,該類別不應在套件 p 外部使用

dart
import 'package:p/src/p.dart';

void f(C c) {}

常見修正方式

#

移除對內部宣告的引用。

無效地使用_null值

#

值始終為 'null' 的表達式無法被取值 (dereferenced)。

描述

#

當值將始終為 null 的表達式被取值時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 x 將始終為 null

dart
int f(Null x) {
  return x.length;
}

常見修正方式

#

如果值允許為 null 以外的其他值,則變更表達式的類型

dart
int f(String? x) {
  return x!.length;
}

在程式庫外部無效地使用類型

#

類別 '{0}' 無法在其程式庫外部擴展,因為它是一個 final 類別。

類別 '{0}' 無法在其程式庫外部擴展,因為它是一個 interface 類別。

類別 '{0}' 無法在其程式庫外部擴展、實作或混入,因為它是一個 sealed 類別。

類別 '{0}' 無法在其程式庫外部實作,因為它是一個 base 類別。

類別 '{0}' 無法在其程式庫外部實作,因為它是一個 final 類別。

類別 '{0}' 無法在其程式庫外部用作 Mixin 超類別約束,因為它是一個 final 類別。

Mixin '{0}' 無法在其程式庫外部實作,因為它是一個 base Mixin。

描述

#

extendsimplementswithon 子句以不允許的方式使用類別或 Mixin,並考慮到該類別或 Mixin 宣告上的修飾詞時,分析器會產生此診斷訊息。

訊息指定了宣告的使用方式以及為何不允許。

範例

#

假設一個檔案 a.dart 定義了一個 base 類別 A

dart
base class A {}

以下程式碼產生此診斷訊息,因為類別 B 實作了類別 A,但 base 修飾詞阻止了 A 在定義它的程式庫外部被實作

dart
import 'a.dart';

final class B implements A {}

常見修正方式

#

此類型的使用在其宣告程式庫外部受到限制。如果存在另一個可提供類似功能且不受限制的類型,請替換該類型

dart
class B implements C {}
class C {}

如果沒有其他合適的類型,則移除該類型,並可能移除整個子句

dart
class B {}

無效地使用可見以進行覆寫的成員

#

成員 '{0}' 只能用於覆寫。

描述

#

當在宣告它的程式庫外部引用以 visibleForOverriding 註解標記的實例成員,且原因不是為了覆寫它時,分析器會產生此診斷訊息。

範例

#

假設一個檔案 a.dart 包含以下宣告

dart
import 'package:meta/meta.dart';

class A {
  @visibleForOverriding
  void a() {}
}

以下程式碼產生此診斷訊息,因為方法 m 正在被調用,即使它公開的唯一原因是允許它被覆寫

dart
import 'a.dart';

class B extends A {
  void b() {
    a();
  }
}

常見修正方式

#

移除成員的無效使用。

無效地使用可見以進行測試的成員

#

成員 '{0}' 只能在 '{1}' 或測試中使用。

描述

#

當在宣告它的程式庫或 test 目錄中的程式庫以外的任何地方引用以 @visibleForTesting 註解標記的成員時,分析器會產生此診斷訊息。

範例

#

假設一個檔案 c.dart 包含以下內容

dart
import 'package:meta/meta.dart';

class C {
  @visibleForTesting
  void m() {}
}

以下程式碼在不在 test 目錄中時產生此診斷訊息,因為方法 m 被標記為僅對測試可見

dart
import 'c.dart';

void f(C c) {
  c.m();
}

常見修正方式

#

如果註解的成員不應在測試外部引用,則移除引用

dart
import 'c.dart';

void f(C c) {}

如果可以在測試外部引用註解的成員,則移除註解

dart
class C {
  void m() {}
}

無效的可見性註解

#

成員 '{0}' 使用 '{1}' 註解,但此註解僅對公開成員的宣告有意義。

描述

#

visibleForTemplatevisibleForTesting 註解套用至非公開宣告時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷訊息

dart
import 'package:meta/meta.dart';

@visibleForTesting
void _someFunction() {}

void f() => _someFunction();

常見修正方式

#

如果宣告不需要被測試程式碼使用,則移除註解

dart
void _someFunction() {}

void f() => _someFunction();

如果需要,則使其公開

dart
import 'package:meta/meta.dart';

@visibleForTesting
void someFunction() {}

void f() => someFunction();

無效的可見以進行覆寫的註解

#

visibleForOverriding 註解只能套用至可以被覆寫的公開實例成員。

描述

#

當類別的公開實例成員以外的任何內容使用 visibleForOverriding 進行註解時,分析器會產生此診斷訊息。由於只有公開實例成員可以在定義程式庫外部被覆寫,因此註解任何其他宣告沒有任何價值。

範例

#

以下程式碼產生此診斷訊息,因為註解是在類別上,而類別無法被覆寫

dart
import 'package:meta/meta.dart';

@visibleForOverriding
class C {}

常見修正方式

#

移除註解

dart
class C {}

無效的可見於範本外部的註解

#

visibleOutsideTemplate 註解只能套用至使用 visibleForTemplate 註解標記的類別、列舉或 Mixin 的成員。

描述

#

@visibleOutsideTemplate 註解被錯誤使用時,分析器會產生此診斷訊息。此註解僅用於註解具有 @visibleForTemplate 註解的類別、列舉或 Mixin 的成員,以使這些成員選擇退出 @visibleForTemplate 強加的可見性限制。

範例

#

以下程式碼產生此診斷訊息,因為在類別層級沒有 @visibleForTemplate 註解

dart
import 'package:angular_meta/angular_meta.dart';

class C {
  @visibleOutsideTemplate
  int m() {
    return 1;
  }
}

以下程式碼產生此診斷訊息,因為註解是在類別宣告上,而不是類別、列舉或 Mixin 的成員上

dart
import 'package:angular_meta/angular_meta.dart';

@visibleOutsideTemplate
class C {}

常見修正方式

#

如果類別僅可見以便模板可以引用它,則將 @visibleForTemplate 註解新增至類別

dart
import 'package:angular_meta/angular_meta.dart';

@visibleForTemplate
class C {
  @visibleOutsideTemplate
  int m() {
    return 1;
  }
}

如果 @visibleOutsideTemplate 註解在任何不是具有 @visibleForTemplate 註解的類別、列舉或 Mixin 的成員上,則移除註解

dart
class C {}

沒有呼叫的擴充功能調用

#

Extension '{0}' 未定義 'call' 方法,因此覆寫不能用於調用中。

描述

#

當 extension 覆寫用於調用函數,但 extension 未宣告 call 方法時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 extension E 未定義 call 方法

dart
extension E on String {}

void f() {
  E('')();
}

常見修正方式

#

如果 extension 的目的是定義 call 方法,則宣告它

dart
extension E on String {
  int call() => 0;
}

void f() {
  E('')();
}

如果擴展類型定義了 call 方法,則移除 extension 覆寫。

如果未定義 call 方法,則重寫程式碼使其不調用 call 方法。

非函式的調用

#

'{0}' 不是函數。

描述

#

當分析器找到函數調用,但被調用函數的名稱被定義為函數以外的其他內容時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 Binary 是函數類型的名稱,而不是函數

dart
typedef Binary = int Function(int, int);

int f() {
  return Binary(1, 2);
}

常見修正方式

#

將名稱替換為函數的名稱。

非函式運算式的調用

#

表達式未求值為函數,因此無法調用它。

描述

#

當找到函數調用,但被引用的名稱不是函數的名稱,或者當計算函數的表達式未計算出函數時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 x 不是函數

dart
int x = 0;

int f() => x;

var y = x();

以下程式碼產生此診斷訊息,因為 f() 未傳回函數

dart
int x = 0;

int f() => x;

var y = f()();

常見修正方式

#

如果您需要調用函數,則將引數列表之前的程式碼替換為函數的名稱或計算函數的表達式

dart
int x = 0;

int f() => x;

var y = f();

外部範圍中的標籤

#

無法引用在外層方法中宣告的標籤 '{0}'。

描述

#

breakcontinue 陳述式引用在包含 breakcontinue 陳述式出現的函數的函數或方法中宣告的標籤時,分析器會產生此診斷訊息。breakcontinue 陳述式不能用於將控制權轉移到包含它們的函數外部。

範例

#

以下程式碼產生此診斷訊息,因為標籤 loop 在本機函數 g 外部宣告

dart
void f() {
  loop:
  while (true) {
    void g() {
      break loop;
    }

    g();
  }
}

常見修正方式

#

嘗試重寫程式碼,使其不必將控制權轉移到本機函數外部,可能通過內聯本機函數

dart
void f() {
  loop:
  while (true) {
    break loop;
  }
}

如果這不可能,則嘗試重寫本機函數,以便可以使用函數傳回的值來確定是否轉移控制權

dart
void f() {
  loop:
  while (true) {
    bool g() {
      return true;
    }

    if (g()) {
      break loop;
    }
  }
}

未定義的標籤

#

無法引用未定義的標籤 '{0}'。

描述

#

當分析器發現對未在引用它的 breakcontinue 陳述式的範圍內定義的標籤的引用時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為標籤 loop 在任何地方都未定義

dart
void f() {
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      if (j != 0) {
        break loop;
      }
    }
  }
}

常見修正方式

#

如果標籤應位於最內層的封閉 doforswitchwhile 陳述式上,則移除標籤

dart
void f() {
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      if (j != 0) {
        break;
      }
    }
  }
}

如果標籤應位於其他某些陳述式上,則新增標籤

dart
void f() {
  loop: for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      if (j != 0) {
        break loop;
      }
    }
  }
}

具有_const_建構子的_late_final_欄位

#

具有產生器 const 建構子的類別中不能有 late final 欄位。

描述

#

當具有至少一個 const 建構子的類別也具有標記為 latefinal 的欄位時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為類別 A 具有 const 建構子,且 final 欄位 f 被標記為 late

dart
class A {
  late final int f;

  const A();
}

常見修正方式

#

如果欄位不需要標記為 late,則從欄位中移除 late 修飾詞

dart
class A {
  final int f = 0;

  const A();
}

如果欄位必須標記為 late,則從建構子中移除 const 修飾詞

dart
class A {
  late final int f;

  A();
}

已賦值的_late_final_區域變數

#

late final 本機變數已指派值。

描述

#

當分析器可以證明標記為 latefinal 的本機變數在另一個指派發生時已經被指派了一個值時,分析器會產生此診斷訊息。

由於 final 變數只能指派一次,因此後續的指派保證會失敗,因此會被標記。

範例

#

以下程式碼產生此診斷訊息,因為 final 變數 v 在兩個地方被指派了值

dart
int f() {
  late final int v;
  v = 0;
  v += 1;
  return v;
}

常見修正方式

#

如果您需要能夠重新指派變數,則移除 final 關鍵字

dart
int f() {
  late int v;
  v = 0;
  v += 1;
  return v;
}

如果您不需要重新指派變數,則移除除第一個指派以外的所有指派

dart
int f() {
  late final int v;
  v = 0;
  return v;
}

leaf_呼叫不得傳回控制代碼

#

FFI 葉節點呼叫不能傳回 'Handle'。

描述

#

Pointer.asFunctionDynamicLibrary.lookupFunction 的調用中 isLeaf 引數的值為 true,且將傳回的函數將具有 Handle 的傳回類型時,分析器會產生此診斷訊息。

Native 註解中的 isLeaf 引數的值為 true,且註解上的類型引數是傳回類型為 Handle 的函數類型時,分析器也會產生此診斷訊息。

在所有這些情況下,葉節點呼叫僅支援類型 boolintfloatdouble,以及作為傳回類型 void

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為函數 p 傳回 Handle,但 isLeaf 引數為 true

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Handle Function()>> p) {
  p.asFunction<Object Function()>(isLeaf: true);
}

常見修正方式

#

如果函數傳回 handle,則移除 isLeaf 引數

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Handle Function()>> p) {
  p.asFunction<Object Function()>();
}

如果函數傳回支援的類型之一,則更正類型資訊

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Int32 Function()>> p) {
  p.asFunction<int Function()>(isLeaf: true);
}

leaf_呼叫不得採用控制代碼

#

FFI 葉節點呼叫不能接受類型為 'Handle' 的引數。

描述

#

Pointer.asFunctionDynamicLibrary.lookupFunction 的調用中 isLeaf 引數的值為 true,且將傳回的函數將具有類型為 Handle 的參數時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為函數 p 具有類型為 Handle 的參數,但 isLeaf 引數為 true

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Void Function(Handle)>> p) {
  p.asFunction<void Function(Object)>(isLeaf: true);
}

常見修正方式

#

如果函數具有至少一個類型為 Handle 的參數,則移除 isLeaf 引數

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Void Function(Handle)>> p) {
  p.asFunction<void Function(Object)>();
}

如果函數的參數都不是 Handle,則更正類型資訊

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Void Function(Int8)>> p) {
  p.asFunction<void Function(int)>(isLeaf: true);
}

清單元素類型不可賦值

#

元素類型 '{0}' 無法指派給 List 類型 '{1}'。

描述

#

當 List 字面值中元素的類型不可指派給 List 的元素類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 2.5 是一個 double,而 List 只能容納整數

dart
List<int> x = [1, 2.5, 3];

常見修正方式

#

如果您打算將不同的物件新增到 List,則將元素替換為計算預期物件的表達式

dart
List<int> x = [1, 2, 3];

如果物件不應在 List 中,則移除元素

dart
List<int> x = [1, 3];

如果計算的物件是正確的,則擴大 List 的元素類型以允許它需要包含的所有不同類型的物件

dart
List<num> x = [1, 2.5, 3];

main第一個位置參數類型

#

'main' 函數的第一個位置參數的類型必須是 'List<String>' 的超類型'.

描述

#

當名為 main 的函數的第一個位置參數不是 List<String> 的超類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 List<int> 不是 List<String> 的超類型

dart
void main(List<int> args) {}

常見修正方式

#

如果函數是一個進入點,則將第一個位置參數的類型變更為 List<String> 的超類型

dart
void main(List<String> args) {}

如果函數不是一個進入點,則變更函數的名稱

dart
void f(List<int> args) {}

main具有必要的具名參數

#

'main' 函數不能有任何必要的具名參數。

描述

#

當名為 main 的函數具有一個或多個必要的具名參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為名為 main 的函數具有一個必要的具名參數 (x)

dart
void main({required int x}) {}

常見修正方式

#

如果函數是一個進入點,則移除 required 關鍵字

dart
void main({int? x}) {}

如果函數不是一個進入點,則變更函數的名稱

dart
void f({required int x}) {}

main具有過多必要的位置參數

#

'main' 函數不能有多於兩個的必要位置參數。

描述

#

當名為 main 的函數具有多於兩個的必要位置參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為函數 main 具有三個必要的位置參數

dart
void main(List<String> args, int x, int y) {}

常見修正方式

#

如果函數是一個進入點,且未使用的額外參數,則移除它們

dart
void main(List<String> args, int x) {}

如果函數是一個進入點,但使用的額外參數用於函數未被用作進入點時,則使額外參數成為可選的

dart
void main(List<String> args, int x, [int y = 0]) {}

如果函數不是一個進入點,則變更函數的名稱

dart
void f(List<String> args, int x, int y) {}

main不是函式

#

名為 'main' 的宣告必須是一個函數。

描述

#

當程式庫包含名稱為 main 的宣告,但該宣告不是頂層函數的宣告時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為名稱 main 正被用於宣告頂層變數

dart
var main = 3;

常見修正方式

#

為宣告使用不同的名稱

dart
var mainIndex = 3;

map中沒有_map_條目

#

Map 條目只能在 Map 字面值中使用。

描述

#

當在 Set 字面值中找到 Map 條目 (鍵/值對) 時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為字面值具有 Map 條目,即使它是一個 Set 字面值

dart
var collection = <String>{'a' : 'b'};

常見修正方式

#

如果您希望集合是一個 Map,則變更程式碼使其成為 Map。在先前的範例中,您可以通過新增另一個類型引數來執行此操作

dart
var collection = <String, String>{'a' : 'b'};

在其他情況下,您可能需要將顯式類型從 Set 變更為 Map

如果您希望集合是一個 Set,則移除 Map 條目,如果兩個值都應包含在 Set 中,則可能將冒號替換為逗號

dart
var collection = <String>{'a', 'b'};

map_金鑰類型不可賦值

#

元素類型 '{0}' 無法指派給 Map 鍵類型 '{1}'。

描述

#

當 Map 字面值中鍵值對的鍵具有的類型不可指派給 Map 的鍵類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 2 是一個 int,但 Map 的鍵必須是 String

dart
var m = <String, String>{2 : 'a'};

常見修正方式

#

如果 Map 的類型是正確的,則變更鍵以具有正確的類型

dart
var m = <String, String>{'2' : 'a'};

如果鍵的類型是正確的,則變更 Map 的鍵類型

dart
var m = <int, String>{2 : 'a'};

map_值類型不可賦值

#

元素類型 '{0}' 無法指派給 Map 值類型 '{1}'。

描述

#

當 Map 字面值中鍵值對的值具有的類型不可指派給 Map 的值類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼產生此診斷訊息,因為 2 是一個 int,但/ Map 的值必須是 String

dart
var m = <String, String>{'a' : 2};

常見修正方式

#

如果 Map 的類型是正確的,則變更值以具有正確的類型

dart
var m = <String, String>{'a' : '2'};

如果值的類型是正確的,則變更 Map 的值類型

dart
var m = <String, int>{'a' : 2};

struct_欄位上不符的註解

#

註解與欄位的宣告類型不符。

描述

#

StructUnion 子類別中欄位的註解與欄位的 Dart 類型不符時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為註解 Double 與 Dart 類型 int 不符

dart
import 'dart:ffi';

final class C extends Struct {
  @Double()
  external int x;
}

常見修正方式

#

如果欄位的類型是正確的,則變更註解以符合

dart
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  external int x;
}

如果註解是正確的,則變更欄位的類型以符合

dart
import 'dart:ffi';

final class C extends Struct {
  @Double()
  external double x;
}

struct_欄位上遺失的註解

#

'{1}' 子類別中類型為 '{0}' 的欄位必須具有指示原生類型的註解。

描述

#

StructUnion 子類別中類型需要註解的欄位沒有註解時,分析器會產生此診斷訊息。Dart 類型 intdoubleArray 用於表示多個 C 類型,而註解指定了欄位表示的相容 C 類型。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼產生此診斷訊息,因為欄位 x 沒有指示整數值底層寬度的註解

dart
import 'dart:ffi';

final class C extends Struct {
  external int x;
}

常見修正方式

#

將適當的註解新增至欄位

dart
import 'dart:ffi';

final class C extends Struct {
  @Int64()
  external int x;
}

遺失的_Dart程式庫

#

必要的程式庫 '{0}' 遺失。

描述

#

當 Dart 或 Flutter SDK 安裝不正確,並因此導致找不到其中一個 dart: 程式庫時,分析器會產生此診斷訊息。

常見修正方式

#

重新安裝 Dart 或 Flutter SDK。

參數遺失預設值

#

參數 '{0}' 的類型不允許空值,但隱含預設值為 'null'。

使用空值安全機制時,請使用 'required' 關鍵字,而非 '@required' 註解。

描述

#

當可選參數(無論是位置參數或具名參數)具有可能非可空類型,且未指定預設值時,分析器會產生此診斷訊息。沒有明確預設值的可選參數,其隱含預設值為 null。如果參數的類型不允許參數具有 null 值,則隱含預設值會無效。

範例

#

以下程式碼會產生此診斷訊息,因為 x 不能為 null,且未指定非 null 的預設值

dart
void f([int x]) {}

以下程式碼也會產生相同訊息

dart
void g({int x}) {}

常見修正方式

#

如果您想使用 null 來表示未提供任何值,則需要將類型設為可空類型

dart
void f([int? x]) {}
void g({int? x}) {}

如果參數不能為空值,則請提供預設值

dart
void f([int x = 1]) {}
void g({int x = 2}) {}

或將參數設為必要參數

dart
void f(int x) {}
void g({required int x}) {}

遺失的相依性

#

遺失匯入套件 '{0}' 的依賴項目。

描述

#

當原始碼中匯入了某個套件,但該套件未列為匯入套件的依賴項目時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為套件 path 未列為依賴項目,但套件 example 的原始碼中存在包含套件 path 的 import 陳述式

yaml
name: example
dependencies:
  meta: ^1.0.2

常見修正方式

#

將遺失的套件 path 新增至 dependencies 欄位

yaml
name: example
dependencies:
  meta: ^1.0.2
  path: any

switch中遺失的列舉常數

#

遺失 '{0}' 的 case 子句。

描述

#

當枚舉的 switch 陳述式未包含枚舉中其中一個值的選項時,分析器會產生此診斷訊息。

請注意,null 始終是枚舉的可能值,因此也必須處理。

範例

#

以下程式碼會產生此診斷訊息,因為未處理枚舉值 e2

dart
enum E { e1, e2 }

void f(E e) {
  switch (e) {
    case E.e1:
      break;
  }
}

常見修正方式

#

如果遺失的值有特殊的處理方式,則請為每個遺失的值新增 case 子句

dart
enum E { e1, e2 }

void f(E e) {
  switch (e) {
    case E.e1:
      break;
    case E.e2:
      break;
  }
}

如果應該以相同方式處理遺失的值,則請新增 default 子句

dart
enum E { e1, e2 }

void f(E e) {
  switch (e) {
    case E.e1:
      break;
    default:
      break;
  }
}

遺失的例外值

#

當函式的傳回類型既不是 'void'、'Handle' 也不是 'Pointer' 時,方法 {0} 必須具有例外傳回值(第二個引數)。

描述

#

Pointer.fromFunctionNativeCallable.isolateLocal 方法的調用缺少第二個引數(例外傳回值),且調用要傳回的類型既不是 voidHandle 也不是 Pointer 時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為 f 傳回的類型預期為 8 位元整數,但對 fromFunction 的呼叫未包含例外傳回引數

dart
import 'dart:ffi';

int f(int i) => i * 2;

void g() {
  Pointer.fromFunction<Int8 Function(Int8)>(f);
}

常見修正方式

#

新增例外傳回類型

dart
import 'dart:ffi';

int f(int i) => i * 2;

void g() {
  Pointer.fromFunction<Int8 Function(Int8)>(f, 0);
}

struct中遺失的欄位類型

#

struct 類別中的欄位必須具有明確宣告的 'int'、'double' 或 'Pointer' 類型。

描述

#

StructUnion 子類別中的欄位沒有類型註解時,分析器會產生此診斷訊息。每個欄位都必須具有明確的類型,且類型必須為 intdoublePointerStructUnion 的子類別。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 str 沒有類型註解

dart
import 'dart:ffi';

final class C extends Struct {
  external var str;

  @Int32()
  external int i;
}

常見修正方式

#

明確指定欄位的類型

dart
import 'dart:ffi';
import 'package:ffi/ffi.dart';

final class C extends Struct {
  external Pointer<Utf8> str;

  @Int32()
  external int i;
}

遺失的名稱

#

'name' 欄位為必要欄位,但遺失了。

描述

#

當沒有最上層 name 鍵時,分析器會產生此診斷訊息。 name 鍵提供套件的名稱,這是必要的。

範例

#

以下程式碼會產生此診斷訊息,因為套件沒有名稱

yaml
dependencies:
  meta: ^1.0.2

常見修正方式

#

新增最上層鍵 name,其值為套件的名稱

yaml
name: example
dependencies:
  meta: ^1.0.2

遺失的具名模式欄位名稱

#

Getter 名稱未明確指定,且模式不是變數。

描述

#

當在物件模式中,屬性的規格和用於比對屬性值的模式,兩者皆不具備下列其中一項時,分析器會產生此診斷訊息:

  • 冒號前的 getter 名稱
  • 可從中推斷 getter 名稱的變數模式

範例

#

以下程式碼會產生此診斷訊息,因為在物件模式 (C(:0)) 中,冒號前沒有 getter 名稱,且冒號後也沒有變數模式

dart
abstract class C {
  int get f;
}

void f(C c) {
  switch (c) {
    case C(:0):
      break;
  }
}

常見修正方式

#

如果您需要在模式的範圍內使用屬性的實際值,則請新增變數模式,其中變數的名稱與要比對的屬性名稱相同

dart
abstract class C {
  int get f;
}

void f(C c) {
  switch (c) {
    case C(:var f) when f == 0:
      print(f);
  }
}

如果您不需要在模式的範圍內使用屬性的實際值,則請在冒號前新增要比對的屬性名稱

dart
abstract class C {
  int get f;
}

void f(C c) {
  switch (c) {
    case C(f: 0):
      break;
  }
}

遺失必須覆寫的覆寫

#

遺失 '{0}' 的具體實作。

遺失 '{0}' 和 '{1}' 的具體實作。

遺失 '{0}'、'{1}' 和其他 {2} 個的具體實作。

描述

#

當具有 @mustBeOverridden 註解的實例成員未在子類別中覆寫時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為當 A.m 標註了 @mustBeOverridden 時,類別 B 沒有繼承方法 A.m 的覆寫

dart
import 'package:meta/meta.dart';

class A {
  @mustBeOverridden
  void m() {}
}

class B extends A {}

常見修正方式

#

如果註解適用於成員,則請在子類別中覆寫成員

dart
import 'package:meta/meta.dart';

class A {
  @mustBeOverridden
  void m() {}
}

class B extends A {
  @override
  void m() {}
}

如果註解不適用於成員,則請移除註解

dart
class A {
  void m() {}
}

class B extends A {}

遺失的必要引數

#

具名參數 '{0}' 為必要參數,但沒有對應的引數。

描述

#

當函式的調用遺失了必要的具名參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 的調用未包含必要具名參數 end 的值

dart
void f(int start, {required int end}) {}
void g() {
  f(3);
}

常見修正方式

#

新增對應於遺失的必要參數的具名引數

dart
void f(int start, {required int end}) {}
void g() {
  f(3, end: 5);
}

遺失的必要參數

#

參數 '{0}' 為必要參數。

參數 '{0}' 為必要參數。{1}。

描述

#

當調用具有標註為必要的具名參數的方法或函式,但未提供參數的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為具名參數 x 為必要參數

dart
import 'package:meta/meta.dart';

void f({@required int? x}) {}

void g() {
  f();
}

常見修正方式

#

提供必要的值

dart
import 'package:meta/meta.dart';

void f({@required int? x}) {}

void g() {
  f(x: 2);
}

遺失的傳回

#

此函式的傳回類型為 '{0}',但未以 return 陳述式結尾。

描述

#

任何未以明確 return 或 throw 結尾的函式或方法都會隱含傳回 null。這很少是期望的行為。當分析器找到隱含傳回時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 未以 return 結尾

dart
int f(int x) {
  if (x < 0) {
    return 0;
  }
}

常見修正方式

#

新增 return 陳述式,使傳回值明確,即使 null 是適當的值。

carray遺失大小註解

#

類型為 'Array' 的欄位必須正好有一個 'Array' 註解。

描述

#

StructUnion 的子類別中的欄位類型為 Array,但沒有單個 Array 註解指示陣列的維度時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 a0 沒有 Array 註解

dart
import 'dart:ffi';

final class C extends Struct {
  external Array<Uint8> a0;
}

常見修正方式

#

確保欄位上正好有一個 Array 註解

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8)
  external Array<Uint8> a0;
}

遺失的變數模式

#

邏輯或模式的此分支中遺失變數模式 '{0}'。

描述

#

當邏輯或模式的一個分支未宣告在同一模式的另一個分支上宣告的變數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為邏輯或模式的右手邊未宣告變數 a

dart
void f((int, int) r) {
  if (r case (var a, 0) || (0, _)) {
    print(a);
  }
}

常見修正方式

#

如果需要在受控陳述式中參考變數,則請將變數的宣告新增至邏輯或模式的每個分支

dart
void f((int, int) r) {
  if (r case (var a, 0) || (0, var a)) {
    print(a);
  }
}

如果不需要在受控陳述式中參考變數,則請從邏輯或模式的每個分支中移除變數的宣告

dart
void f((int, int) r) {
  if (r case (_, 0) || (0, _)) {
    print('found a zero');
  }
}

如果只有在模式的一個分支符合時才需要參考變數,而在另一個分支符合時則不需要,則請將模式分成兩部分

dart
void f((int, int) r) {
  switch (r) {
    case (var a, 0):
      print(a);
    case (0, _):
      print('found a zero');
  }
}

mixin應用具體父類別叫用成員類型

#

Super 呼叫的成員 '{0}' 的類型為 '{1}',而類別中的具體成員的類型為 '{2}'。

描述

#

當在類別中使用 mixin,且該 mixin 使用 super 調用方法,但該方法的具體實作與 mixin 的 on 類型為該方法定義的簽章不同時,分析器會產生此診斷訊息。之所以會發生錯誤,是因為 mixin 中的調用可能會以與實際執行的方法不相容的方式調用該方法。

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 使用 mixin M,mixin M 使用 super 調用 foo,且在 I(mixin 的 on 類型)中宣告的抽象版本的 foo 與在 A 中宣告的具體版本的 foo 簽章不同

dart
class I {
  void foo([int? p]) {}
}

class A {
  void foo(int p) {}
}

abstract class B extends A implements I {
  @override
  void foo([int? p]);
}

mixin M on I {
  void bar() {
    super.foo(42);
  }
}

abstract class C extends B with M {}

常見修正方式

#

如果類別不需要使用 mixin,則請從 with 子句中移除它

dart
class I {
  void foo([int? p]) {}
}

class A {
  void foo(int? p) {}
}

abstract class B extends A implements I {
  @override
  void foo([int? p]);
}

mixin M on I {
  void bar() {
    super.foo(42);
  }
}

abstract class C extends B {}

如果類別需要使用 mixin,則請確保方法的具體實作符合 mixin 期望的簽章

dart
class I {
  void foo([int? p]) {}
}

class A {
  void foo(int? p) {}
}

abstract class B extends A implements I {
  @override
  void foo([int? p]) {
    super.foo(p);
  }
}

mixin M on I {
  void bar() {
    super.foo(42);
  }
}

abstract class C extends B with M {}

mixin應用未實作介面

#

'{0}' 無法混入 '{1}',因為 '{1}' 未實作 '{2}'。

描述

#

當具有超類別約束的 mixin 用於mixin 應用,但其超類別未實作必要的約束時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 mixin M 要求應用它的類別必須是 A 的子類別,但 Object 不是 A 的子類別

dart
class A {}

mixin M on A {}

class X = Object with M;

常見修正方式

#

如果您需要使用 mixin,則請將超類別變更為與超類別約束相同或為其子類別

dart
class A {}

mixin M on A {}

class X = A with M;

mixin應用沒有具體的父類別叫用成員

#

類別沒有 super 呼叫成員 '{0}' 的具體實作。

類別沒有 super 呼叫 setter '{0}' 的具體實作。

描述

#

mixin 應用包含從其超類別調用成員,且 mixin 應用的超類別中沒有該名稱的具體成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 mixin M 包含調用 super.m(),且類別 A(即 mixin 應用 A+M 的超類別)未定義 m 的具體實作

dart
abstract class A {
  void m();
}

mixin M on A {
  void bar() {
    super.m();
  }
}

abstract class B extends A with M {}

常見修正方式

#

如果您打算將 mixin M 應用於不同的類別,即具有 m 的具體實作的類別,則請將 B 的超類別變更為該類別

dart
abstract class A {
  void m();
}

mixin M on A {
  void bar() {
    super.m();
  }
}

class C implements A {
  void m() {}
}

abstract class B extends C with M {}

如果您需要使 B 成為 A 的子類別,則請在 A 中新增 m 的具體實作

dart
abstract class A {
  void m() {}
}

mixin M on A {
  void bar() {
    super.m();
  }
}

abstract class B extends A with M {}

mixin類別宣告擴充非物件

#

類別 '{0}' 無法宣告為 mixin,因為它擴展了 'Object' 以外的類別。

描述

#

當標記為 mixin 修飾詞的類別擴展了 'Object' 以外的類別時,分析器會產生此診斷訊息。mixin 類別不能有 'Object' 以外的超類別。

範例

#

以下程式碼會產生此診斷訊息,因為具有修飾詞 mixin 的類別 B 擴展了 A

dart
class A {}

mixin class B extends A {}

常見修正方式

#

如果您希望將類別用作 mixin,則請將超類別變更為 Object,可以明確變更,也可以移除 extends 子句來變更

dart
class A {}

mixin class B {}

如果類別需要具有 'Object' 以外的超類別,則請移除 mixin 修飾詞

dart
class A {}

class B extends A {}

如果您既需要 mixin 又需要 'Object' 以外的類別的子類別,則請將子類別的成員移至新的 mixin,從子類別中移除 mixin 修飾詞,並將新的 mixin 應用於子類別

dart
class A {}

class B extends A with M {}

mixin M {}

根據子類別的成員,這可能需要為 mixin 新增 on 子句。

mixin類別宣告建構子

#

類別 '{0}' 無法用作 mixin,因為它宣告了建構子。

描述

#

當類別用作 mixin,且混入的類別定義了建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 A(定義了建構子)正在用作 mixin

dart
//@dart=2.19
class A {
  A();
}

class B with A {}

常見修正方式

#

如果可以將類別轉換為 mixin,則請執行轉換

dart
mixin A {
}

class B with A {}

如果類別不能是 mixin,且可以移除建構子,則請執行移除

dart
//@dart=2.19
class A {
}

class B with A {}

如果類別不能是 mixin,且您無法移除建構子,則請嘗試擴展或實作類別,而不是混入它

dart
class A {
  A();
}

class B extends A {}

mixin繼承自非物件

#

類別 '{0}' 無法用作 mixin,因為它擴展了 'Object' 以外的類別。

描述

#

當擴展了 'Object' 以外的類別的類別用作 mixin 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 B(擴展了 A)正被 C 用作 mixin

dart
//@dart=2.19
class A {}

class B extends A {}

class C with B {}

常見修正方式

#

如果用作 mixin 的類別可以變更為擴展 Object,則請變更它

dart
//@dart=2.19
class A {}

class B {}

class C with B {}

如果用作 mixin 的類別無法變更,且使用它的類別擴展了 Object,則請擴展用作 mixin 的類別

dart
class A {}

class B extends A {}

class C extends B {}

如果類別未擴展 Object,或者您希望能夠在其他位置混入 B 的行為,則請建立真正的 mixin

dart
class A {}

mixin M on A {}

class B extends A with M {}

class C extends A with M {}

mixin具現化

#

Mixin 無法實例化。

描述

#

當 mixin 被實例化時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 mixin M 正在被實例化

dart
mixin M {}

var m = M();

常見修正方式

#

如果您打算使用類別的實例,則請使用該類別的名稱來取代 mixin 的名稱。

mixin的非類別

#

類別只能混入 mixin 和類別。

描述

#

with 子句中的名稱定義為 mixin 或類別以外的其他項目時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 F 定義為函式類型

dart
typedef F = int Function(String);

class C with F {}

常見修正方式

#

從清單中移除無效的名稱,可能會將其替換為預期的 mixin 或類別的名稱

dart
typedef F = int Function(String);

class C {}

sealed_類別上的_mixin

#

類別 '{0}' 不應作為 mixin 約束使用,因為它是 sealed 類別,且任何混入此 mixin 的類別都必須以 '{0}' 作為超類別。

描述

#

當 mixin 的超類別約束是來自不同套件的類別,且該類別標記為 sealed 時,分析器會產生此診斷訊息。 Sealed 類別無法擴展、實作、混入或用作超類別約束。

範例

#

如果套件 p 定義了 sealed 類別

dart
import 'package:meta/meta.dart';

@sealed
class C {}

則以下程式碼在套件 p 以外的套件中時,會產生此診斷訊息

dart
import 'package:p/p.dart';

mixin M on C {}

常見修正方式

#

如果使用 mixin 的類別不需要成為 sealed 類別的子類別,則請考慮新增欄位並委派給 sealed 類別的包裝實例。

mixin_父類別限制延遲載入類別

#

延遲類別無法用作超類別約束。

描述

#

當 mixin 的超類別約束是從延遲載入的程式庫匯入時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 math.Random 的超類別約束是從延遲載入的程式庫匯入

dart
import 'dart:async' deferred as async;

mixin M<T> on async.Stream<T> {}

常見修正方式

#

如果匯入不需要延遲載入,則請移除 deferred 關鍵字

dart
import 'dart:async' as async;

mixin M<T> on async.Stream<T> {}

如果匯入確實需要延遲載入,則請移除超類別約束

dart
mixin M<T> {}

mixin_父類別限制非介面

#

只有類別和 mixin 可以用作超類別約束。

描述

#

當 mixin 宣告中 on 關鍵字後面的類型既不是類別也不是 mixin 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 F 既不是類別也不是 mixin

dart
typedef F = void Function();

mixin M on F {}

常見修正方式

#

如果類型原本應為類別,但輸入錯誤,則請替換名稱。

否則,請從 on 子句中移除類型。

多個重新導向建構子調用

#

建構子最多只能有一個 'this' 重新導向。

描述

#

當建構子重新導向到同一個類別中的多個其他建構子 (使用 this) 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 C 中的未命名建構子同時重新導向到 this.athis.b

dart
class C {
  C() : this.a(), this.b();
  C.a();
  C.b();
}

常見修正方式

#

移除所有重新導向,僅保留一個

dart
class C {
  C() : this.a();
  C.a();
  C.b();
}

多個_super_初始化器

#

建構子最多只能有一個 'super' 初始化運算式。

描述

#

當建構子的初始化運算式清單包含多個從超類別調用建構子的情況時,分析器會產生此診斷訊息。初始化運算式清單必須正好有一個此類呼叫,可以是明確的或隱含的。

範例

#

以下程式碼會產生此診斷訊息,因為 B 的建構子的初始化運算式清單同時調用了超類別 A 中的建構子 one 和建構子 two

dart
class A {
  int? x;
  String? s;
  A.one(this.x);
  A.two(this.s);
}

class B extends A {
  B() : super.one(0), super.two('');
}

常見修正方式

#

如果其中一個 super 建構子將完全初始化實例,則請移除另一個

dart
class A {
  int? x;
  String? s;
  A.one(this.x);
  A.two(this.s);
}

class B extends A {
  B() : super.one(0);
}

如果其中一個 super 建構子實現的初始化可以在建構子的主體中執行,則請移除其 super 調用,並在主體中執行初始化

dart
class A {
  int? x;
  String? s;
  A.one(this.x);
  A.two(this.s);
}

class B extends A {
  B() : super.one(0) {
    s = '';
  }
}

如果初始化只能在超類別的建構子中執行,則請新增新的建構子,或修改現有的建構子之一,以便有一個建構子允許在單次呼叫中完成所有必要的初始化

dart
class A {
  int? x;
  String? s;
  A.one(this.x);
  A.two(this.s);
  A.three(this.x, this.s);
}

class B extends A {
  B() : super.three(0, '');
}

必須是原生函式類型

#

給予 '{1}' 的類型 '{0}' 必須是有效的 'dart:ffi' 原生函式類型。

描述

#

當調用 Pointer.fromFunctionDynamicLibrary.lookupFunctionNativeCallable 建構子時,其類型引數(無論是明確的還是推斷的)不是原生函式類型時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為類型 T 可以是 Function 的任何子類別,但 fromFunction 的類型引數必須是原生函式類型

dart
import 'dart:ffi';

int f(int i) => i * 2;

class C<T extends Function> {
  void g() {
    Pointer.fromFunction<T>(f, 0);
  }
}

常見修正方式

#

使用原生函式類型作為調用的類型引數

dart
import 'dart:ffi';

int f(int i) => i * 2;

class C<T extends Function> {
  void g() {
    Pointer.fromFunction<Int32 Function(Int32)>(f, 0);
  }
}

必須是子類型

#

對於 '{2}',類型 '{0}' 必須是 '{1}' 的子類型。

描述

#

分析器在兩種情況下會產生此診斷訊息

  • Pointer.fromFunction 的調用中,或 NativeCallable 建構子中,類型引數(無論是明確的還是推斷的)不是傳遞為方法第一個引數的函式類型的超類型。
  • DynamicLibrary.lookupFunction 的調用中,第一個類型引數不是第二個類型引數的超類型。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為函式 f 的類型 (String Function(int)) 不是類型引數 T (Int8 Function(Int8)) 的子類型

dart
import 'dart:ffi';

typedef T = Int8 Function(Int8);

double f(double i) => i;

void g() {
  Pointer.fromFunction<T>(f, 5.0);
}

常見修正方式

#

如果函式正確,則請變更類型引數以符合

dart
import 'dart:ffi';

typedef T = Float Function(Float);

double f(double i) => i;

void g() {
  Pointer.fromFunction<T>(f, 5.0);
}

如果類型引數正確,則請變更函式以符合

dart
import 'dart:ffi';

typedef T = Int8 Function(Int8);

int f(int i) => i;

void g() {
  Pointer.fromFunction<T>(f, 5);
}

必須是不可變的

#

此類別(或此類別繼承自的類別)標記為 '@immutable',但其一個或多個實例欄位不是 final:{0}

描述

#

當不可變類別定義了一個或多個非 final 的實例欄位時,分析器會產生此診斷訊息。如果類別使用註解 immutable 標記為不可變,或者它是不可變類別的子類別,則該類別是不可變的。

範例

#

以下程式碼會產生此診斷,因為欄位 x 不是 final

dart
import 'package:meta/meta.dart';

@immutable
class C {
  int x;

  C(this.x);
}

常見修正方式

#

如果類別的實例應該是不可變的,則請將關鍵字 final 新增至所有非 final 欄位宣告

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final int x;

  C(this.x);
}

如果類別的實例應該是可變的,則請移除註解,或者如果註解是繼承的,則選擇不同的超類別

dart
class C {
  int x;

  C(this.x);
}

必須呼叫_super

#

此方法覆寫了 '{0}' 中標註為 '@mustCallSuper' 的方法,但未調用覆寫的方法。

描述

#

當覆寫標註為 mustCallSuper 的方法的方法未按要求調用覆寫的方法時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 B 中的方法 m 未調用 A 中覆寫的方法 m

dart
import 'package:meta/meta.dart';

class A {
  @mustCallSuper
  m() {}
}

class B extends A {
  @override
  m() {}
}

常見修正方式

#

在覆寫方法中新增覆寫方法的調用

dart
import 'package:meta/meta.dart';

class A {
  @mustCallSuper
  m() {}
}

class B extends A {
  @override
  m() {
    super.m();
  }
}

必須傳回_void

#

傳遞給 'NativeCallable.listener' 的函式的傳回類型必須是 'void',而不是 '{0}'。

描述

#

當您將不傳回 void 的函式傳遞給 NativeCallable.listener 建構子時,分析器會產生此診斷訊息。

NativeCallable.listener 建立一個可以從任何執行緒調用的原生可調用物件。調用可調用物件的原生程式碼會將訊息傳回給建立可調用物件的隔離區,且不會等待回應。因此,無法從可調用物件傳回結果。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為函式 f 傳回 int 而不是 void

dart
import 'dart:ffi';

int f(int i) => i * 2;

void g() {
  NativeCallable<Int32 Function(Int32)>.listener(f);
}

常見修正方式

#

將函式的傳回類型變更為 void

dart
import 'dart:ffi';

void f(int i) => print(i * 2);

void g() {
  NativeCallable<Void Function(Int32)>.listener(f);
}

名稱不是字串

#

'name' 欄位的值必須是字串。

描述

#

當最上層 name 鍵的值不是字串時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 name 鍵後面的值是一個清單

yaml
name:
  - example

常見修正方式

#

將值替換為字串

yaml
name: example

原生欄位無效的類型

#

'{0}' 是原生欄位不支援的類型。原生欄位僅支援指標、陣列或數值和複合類型。

描述

#

@Native 註解的欄位具有原生欄位不支援的類型時,分析器會產生此診斷訊息。

原生欄位支援指標、陣列、數值類型和 Compound 的子類型(即 struct 或 union)。NativeType 的其他子類型,例如 HandleNativeFunction,不允許作為原生欄位。

原生函式應與外部函式一起使用,而不是外部欄位。

不支援 Handle,因為無法透明地將 Dart 物件載入和儲存到指標中。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 free 使用了不支援的原生類型 NativeFunction

dart
import 'dart:ffi';

@Native<NativeFunction<Void Function()>>()
external void Function() free;

常見修正方式

#

如果您打算使用 NativeFunction 欄位繫結到現有的原生函式,請改用 @Native 方法

dart
import 'dart:ffi';

@Native<Void Function(Pointer<Void>)>()
external void free(Pointer<Void> ptr);

若要繫結到 C 中儲存函式指標的欄位,請為 Dart 欄位使用指標類型

dart
import 'dart:ffi';

@Native()
external Pointer<NativeFunction<Void Function(Pointer<Void>)>> free;

原生欄位遺失類型

#

無法推斷此欄位的原生類型,必須在註解中指定。

描述

#

@Native 註解的欄位需要在註解中提供類型提示才能推斷原生類型時,分析器會產生此診斷訊息。

Dart 類型(例如 intdouble)具有多種可能的原生表示法。由於需要在編譯時知道原生類型,以便在存取欄位時產生正確的載入和儲存指令,因此必須提供明確的類型。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 f 的類型為 int(有多種原生表示法),但在 Native 註解上沒有明確的類型參數

dart
import 'dart:ffi';

@Native()
external int f;

常見修正方式

#

若要修正此診斷訊息,請從欄位的原生宣告中找出正確的原生表示法。然後,將對應的類型新增至註解。例如,如果 f 在 C 中宣告為 uint8_t,則 Dart 欄位應宣告為

dart
import 'dart:ffi';

@Native<Uint8>()
external int f;

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

原生欄位不是靜態的

#

原生欄位必須是靜態的。

描述

#

當類別中的實例欄位標註了 @Native 時,分析器會產生此診斷訊息。原生欄位是指 C、C++ 或其他原生語言中的全域變數,而 Dart 中的實例欄位特定於該類別的實例。因此,原生欄位必須是靜態的。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 中的欄位 f@Native,但不是 static

dart
import 'dart:ffi';

class C {
  @Native<Int>()
  external int f;
}

常見修正方式

#

將欄位設為靜態

dart
import 'dart:ffi';

class C {
  @Native<Int>()
  external static int f;
}

或將其移出類別,在這種情況下,不需要明確的 static 修飾詞

dart
import 'dart:ffi';

class C {
}

@Native<Int>()
external int f;

如果您打算註解應為 struct 一部分的實例欄位,請省略 @Native 註解

dart
import 'dart:ffi';

final class C extends Struct {
  @Int()
  external int f;
}

原生函式遺失類型

#

無法推斷此函式的原生類型,因此必須在註解中指定。

描述

#

@Native 註解的函式需要在註解中提供類型提示才能推斷原生函式類型時,分析器會產生此診斷訊息。

Dart 類型(例如 intdouble)具有多種可能的原生表示法。由於需要在編譯時知道原生類型,以便為函式產生正確的繫結和呼叫指令,因此必須提供明確的類型。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為函式 f() 的傳回類型為 int,但在 Native 註解上沒有明確的類型參數

dart
import 'dart:ffi';

@Native()
external int f();

常見修正方式

#

將對應的類型新增至註解。例如,如果 f() 在 C 中宣告為傳回 int32_t,則 Dart 函式應宣告為

dart
import 'dart:ffi';

@Native<Int32 Function()>()
external int f();

負數變數維度

#

可變長度陣列的變數維度必須是非負數。

描述

#

分析器在兩種情況下會產生此診斷。

第一種情況是 Array.variableWithVariableDimension 註解中給定的變數維度為負數。變數維度是註解中的第一個引數。

第二種情況是 Array.variableMulti 註解中給定的變數維度為負數。變數維度在註解的 variableDimension 引數中指定。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為在 Array.variableWithVariableDimension 註解中提供了變數維度 -1

dart
import 'dart:ffi';

final class MyStruct extends Struct {
  @Array.variableWithVariableDimension(-1)
  external Array<Uint8> a0;
}

以下程式碼會產生此診斷訊息,因為在 Array.variableMulti 註解中提供了變數維度 -1

dart
import 'dart:ffi';

final class MyStruct2 extends Struct {
  @Array.variableMulti(variableDimension: -1, [1, 2])
  external Array<Array<Array<Uint8>>> a0;
}

常見修正方式

#

將變數維度變更為零 (0) 或正數

dart
import 'dart:ffi';

final class MyStruct extends Struct {
  @Array.variableWithVariableDimension(1)
  external Array<Uint8> a0;
}

將變數維度變更為零 (0) 或正數

dart
import 'dart:ffi';

final class MyStruct2 extends Struct {
  @Array.variableMulti(variableDimension: 1, [1, 2])
  external Array<Array<Array<Uint8>>> a0;
}

具有未定義建構子預設值的_new

#

類別 '{0}' 沒有未命名的建構子。

描述

#

當在定義了具名建構子的類別上調用未命名的建構子,但該類別沒有未命名的建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 A 未定義未命名的建構子

dart
class A {
  A.a();
}

A f() => A();

常見修正方式

#

如果其中一個具名建構子可以滿足您的需求,則請使用它

dart
class A {
  A.a();
}

A f() => A.a();

如果沒有具名建構子可以滿足您的需求,且您可以新增未命名的建構子,則請新增建構子

dart
class A {
  A();
  A.a();
}

A f() => A();

非抽象類別繼承抽象成員

#

遺失 '{0}' 的具體實作。

遺失 '{0}' 和 '{1}' 的具體實作。

遺失 '{0}'、'{1}'、'{2}'、'{3}' 和其他 {4} 個的具體實作。

遺失 '{0}'、'{1}'、'{2}' 和 '{3}' 的具體實作。

遺失 '{0}'、'{1}' 和 '{2}' 的具體實作。

描述

#

當具體類別繼承了一個或多個抽象成員,且未為至少其中一個抽象成員提供或繼承實作時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 B 沒有 m 的具體實作

dart
abstract class A {
  void m();
}

class B extends A {}

常見修正方式

#

如果子類別可以為某些或所有繼承的抽象成員提供具體實作,則請新增具體實作

dart
abstract class A {
  void m();
}

class B extends A {
  void m() {}
}

如果存在提供繼承方法實作的 mixin,則請將 mixin 應用於子類別

dart
abstract class A {
  void m();
}

class B extends A with M {}

mixin M {
  void m() {}
}

如果子類別無法為所有繼承的抽象成員提供具體實作,則請將子類別標記為抽象類別

dart
abstract class A {
  void m();
}

abstract class B extends A {}

非布林條件

#

條件必須具有 'bool' 的靜態類型。

描述

#

當條件(例如 ifwhile 迴圈)沒有 bool 的靜態類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 x 具有 int 的靜態類型

dart
void f(int x) {
  if (x) {
    // ...
  }
}

常見修正方式

#

變更條件,使其產生布林值

dart
void f(int x) {
  if (x == 0) {
    // ...
  }
}

非布林運算式

#

assert 中的運算式必須為 'bool' 類型。

描述

#

當 assert 中的第一個運算式的類型不是 bool 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 p 的類型為 int,但需要 bool

dart
void f(int p) {
  assert(p);
}

常見修正方式

#

變更運算式,使其具有 bool 類型

dart
void f(int p) {
  assert(p > 0);
}

非布林否定運算式

#

否定運算元必須具有 'bool' 的靜態類型。

描述

#

當一元否定運算子 (!) 的運算元沒有 bool 類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 xint,但它必須是 bool

dart
int x = 0;
bool y = !x;

常見修正方式

#

將運算元替換為具有 bool 類型的運算式

dart
int x = 0;
bool y = !(x > 0);

非布林運算元

#

運算子 '{0}' 的運算元必須可指派給 'bool'。

描述

#

&&|| 運算子之一的運算元沒有 bool 類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 a 不是布林值

dart
int a = 3;
bool b = a || a > 1;

常見修正方式

#

將運算元變更為布林值

dart
int a = 3;
bool b = a == 0 || a > 1;

非常數註解建構子

#

註解建立只能呼叫 const 建構子。

描述

#

當註解是對現有建構子的調用,即使調用的建構子不是 const 建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 C 的建構子不是 const 建構子

dart
@C()
void f() {
}

class C {
  C();
}

常見修正方式

#

如果類別可以具有 const 建構子,則請建立可用於註解的 const 建構子

dart
@C()
void f() {
}

class C {
  const C();
}

如果類別不能具有 const 建構子,則請移除註解,或為註解使用不同的類別。

非常數_case_運算式

#

Case 運算式必須是常數。

描述

#

case 子句中的運算式不是常數運算式時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷,因為 j 不是常數

dart
void f(int i, int j) {
  switch (i) {
    case j:
      // ...
      break;
  }
}

常見修正方式

#

請將運算式設為常數運算式,或將 switch 述句改寫為一連串的 if 述句

dart
void f(int i, int j) {
  if (i == j) {
    // ...
  }
}

來自延遲載入程式庫的非常數_case_運算式

#

延遲載入函式庫的常數值不能做為 case 運算式使用。

描述

#

當 case 子句中的運算式參照到使用延遲匯入的函式庫中的常數時,分析器會產生此診斷。為了讓 switch 述句能夠有效率地編譯,case 子句中參照的常數必須在編譯時期可用,而延遲載入函式庫中的常數在編譯時期是不可用的。

有關更多資訊,請查看 延遲載入程式庫

範例

#

給定一個檔案 a.dart,它定義了常數 zero

dart
const zero = 0;

下列程式碼會產生此診斷,因為函式庫 a.dart 是使用 deferred 匯入,且在 case 子句中使用了匯入函式庫中宣告的常數 a.zero

dart
import 'a.dart' deferred as a;

void f(int x) {
  switch (x) {
    case a.zero:
      // ...
      break;
  }
}

常見修正方式

#

如果您需要參照匯入函式庫中的常數,請移除 deferred 關鍵字

dart
import 'a.dart' as a;

void f(int x) {
  switch (x) {
    case a.zero:
      // ...
      break;
  }
}

如果您需要參照匯入函式庫中的常數,且也需要延遲匯入該函式庫,請將 switch 述句改寫為一連串的 if 述句

dart
import 'a.dart' deferred as a;

void f(int x) {
  if (x == a.zero) {
    // ...
  }
}

如果您不需要參照常數,請替換 case 運算式

dart
void f(int x) {
  switch (x) {
    case 0:
      // ...
      break;
  }
}

非常數預設值

#

選用參數的預設值必須是常數。

描述

#

當具名或位置選用參數的預設值不是編譯時期常數時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷訊息

dart
var defaultValue = 3;

void f([int value = defaultValue]) {}

常見修正方式

#

如果預設值可以轉換為常數,請轉換它

dart
const defaultValue = 3;

void f([int value = defaultValue]) {}

如果預設值需要隨時間變更,請在函式內部套用預設值

dart
var defaultValue = 3;

void f([int? value]) {
  value ??= defaultValue;
}

來自延遲載入程式庫的非常數預設值

#

延遲載入函式庫的常數值不能做為預設參數值使用。

描述

#

當選用參數的預設值使用從延遲匯入的函式庫匯入的常數時,分析器會產生此診斷。預設值需要在編譯時期可用,而延遲載入函式庫中的常數在編譯時期是不可用的。

有關更多資訊,請查看 延遲載入程式庫

範例

#

給定一個檔案 a.dart,它定義了常數 zero

dart
const zero = 0;

下列程式碼會產生此診斷,因為 zero 是在使用延遲匯入的函式庫中宣告的

dart
import 'a.dart' deferred as a;

void f({int x = a.zero}) {}

常見修正方式

#

如果您需要參照匯入函式庫中的常數,請移除 deferred 關鍵字

dart
import 'a.dart' as a;

void f({int x = a.zero}) {}

如果您不需要參照常數,請替換預設值

dart
void f({int x = 0}) {}

非常數清單元素

#

常數列表常值中的值必須是常數。

描述

#

當常數列表常值中的元素不是常數值時,分析器會產生此診斷。列表常值可以是明確的常數 (因為它以 const 關鍵字作為前綴) 或隱含的常數 (因為它出現在常數情境中)。

範例

#

下列程式碼會產生此診斷,因為 x 不是常數,即使它出現在隱含的常數列表常值中

dart
var x = 2;
var y = const <int>[0, 1, x];

常見修正方式

#

如果列表需要是常數列表,請將元素轉換為常數。在上述範例中,您可以將 const 關鍵字新增至 x 的宣告中

dart
const x = 2;
var y = const <int>[0, 1, x];

如果運算式無法設為常數,則列表也不能是常數,因此您必須變更程式碼,使列表不是常數。在上述範例中,這表示移除列表常值之前的 const 關鍵字

dart
var x = 2;
var y = <int>[0, 1, x];

非常數_map_元素

#

常數映射常值中的元素必須是常數。

描述

#

當常數映射中的 if 元素或展開元素不是常數元素時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為它嘗試展開非常數映射

dart
var notConst = <int, int>{};
var map = const <int, int>{...notConst};

同樣地,下列程式碼會產生此診斷,因為 if 元素中的條件不是常數運算式

dart
bool notConst = true;
var map = const <int, int>{if (notConst) 1 : 2};

常見修正方式

#

如果映射需要是常數映射,請將元素設為常數。在展開範例中,您可以將要展開的集合設為常數來做到這一點

dart
const notConst = <int, int>{};
var map = const <int, int>{...notConst};

如果映射不需要是常數映射,請移除 const 關鍵字

dart
bool notConst = true;
var map = <int, int>{if (notConst) 1 : 2};

非常數_map_金鑰

#

常數映射常值中的鍵必須是常數。

描述

#

當常數映射常值中的鍵不是常數值時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 a 不是常數

dart
var a = 'a';
var m = const {a: 0};

常見修正方式

#

如果映射需要是常數映射,請將鍵設為常數

dart
const a = 'a';
var m = const {a: 0};

如果映射不需要是常數映射,請移除 const 關鍵字

dart
var a = 'a';
var m = {a: 0};

非常數_map_模式金鑰

#

映射模式中的鍵運算式必須是常數。

描述

#

當映射模式中的鍵不是常數運算式時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為鍵 A() 不是常數

dart
void f(Object x) {
  if (x case {A(): 0}) {}
}

class A {
  const A();
}

常見修正方式

#

請使用常數作為鍵

dart
void f(Object x) {
  if (x case {const A(): 0}) {}
}

class A {
  const A();
}

非常數_map_

#

常數映射常值中的值必須是常數。

描述

#

當常數映射常值中的值不是常數值時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 a 不是常數

dart
var a = 'a';
var m = const {0: a};

常見修正方式

#

如果映射需要是常數映射,請將鍵設為常數

dart
const a = 'a';
var m = const {0: a};

如果映射不需要是常數映射,請移除 const 關鍵字

dart
var a = 'a';
var m = {0: a};

非常數關係模式運算式

#

關係模式運算式必須是常數。

描述

#

當關係模式運算式中的值不是常數運算式時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 > 運算子的運算元 a 不是常數

dart
final a = 0;

void f(int x) {
  if (x case > a) {}
}

常見修正方式

#

請將值替換為常數運算式

dart
const a = 0;

void f(int x) {
  if (x case > a) {}
}

非常數_set_元素

#

常數集合常值中的值必須是常數。

描述

#

當常數集合常值包含不是編譯時期常數的元素時,分析器會產生此診斷。

範例

#

以下程式碼會產生此診斷,因為 i 不是常數

dart
var i = 0;

var s = const {i};

常見修正方式

#

如果元素可以變更為常數,請變更它

dart
const i = 0;

var s = const {i};

如果元素不能是常數,請移除關鍵字 const

dart
var i = 0;

var s = {i};

非常數類型引數

#

「{0}」的型別引數必須在編譯時期已知,因此它們不能是型別參數。

描述

#

當方法的型別引數需要於編譯時期已知,但使用了型別參數 (其值在編譯時期可能未知) 作為型別引數時,分析器會產生此診斷。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

下列程式碼會產生此診斷,因為 Pointer.asFunction 的型別引數必須在編譯時期已知,但是型別參數 R (在編譯時期未知) 正被用作型別引數

dart
import 'dart:ffi';

typedef T = int Function(int);

class C<R extends T> {
  void m(Pointer<NativeFunction<T>> p) {
    p.asFunction<R>();
  }
}

常見修正方式

#

請移除任何型別參數的使用

dart
import 'dart:ffi';

class C {
  void m(Pointer<NativeFunction<Int64 Function(Int64)>> p) {
    p.asFunction<int Function(int)>();
  }
}

const_參數的非常數引數

#

引數 '{0}' 必須是常數。

描述

#

當參數使用 mustBeConst 註解標註,且對應的引數不是常數運算式時,分析器會產生此診斷。

範例

#

下列程式碼會在函式 f 的調用上產生此診斷,因為傳遞給函式 g 的引數值不是常數

dart
import 'package:meta/meta.dart' show mustBeConst;

int f(int value) => g(value);

int g(@mustBeConst int value) => value + 1;

常見修正方式

#

如果有可用的合適常數可以使用,請將引數替換為常數

dart
import 'package:meta/meta.dart' show mustBeConst;

const v = 3;

int f() => g(v);

int g(@mustBeConst int value) => value + 1;

字面值建構子的非常數呼叫

#

這個執行個體建立必須是 'const',因為 {0} 建構子標記為 '@literal'。

描述

#

當具有 literal 註解的建構子在沒有使用 const 關鍵字的情況下被調用,但建構子的所有引數都是常數時,分析器會產生此診斷。此註解表示建構子應盡可能用於建立常數值。

範例

#

下列程式碼會產生此診斷訊息

dart
import 'package:meta/meta.dart';

class C {
  @literal
  const C();
}

C f() => C();

常見修正方式

#

請在建構子調用之前新增關鍵字 const

dart
import 'package:meta/meta.dart';

class C {
  @literal
  const C();
}

void f() => const C();

非常數產生器列舉建構子

#

生成式列舉建構子必須是 'const'。

描述

#

當列舉宣告包含未標記為 const 的生成式建構子時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 E 中的建構子未標記為 const

dart
enum E {
  e;

  E();
}

常見修正方式

#

請在建構子之前新增 const 關鍵字

dart
enum E {
  e;

  const E();
}

表示法類型中非變異數類型參數位置

#

擴充型別參數不能在其表示型別的非協變位置中使用。

描述

#

當擴充型別的型別參數在該擴充型別的表示型別中的非協變位置中使用時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為型別參數 T 在函式型別 void Function(T) 中用作參數型別,而參數不是協變的

dart
extension type A<T>(void Function(T) f) {}

常見修正方式

#

請移除型別參數的使用

dart
extension type A(void Function(String) f) {}

非詳盡的_switch_運算式

#

類型「{0}」未被 switch case 完全比對,因為它與「{1}」不符。

描述

#

switch 運算式缺少一個或多個可能流經它的值的情況時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 switch 運算式沒有值 E.three 的 case

dart
enum E { one, two, three }

String f(E e) => switch (e) {
    E.one => 'one',
    E.two => 'two',
  };

常見修正方式

#

如果遺失的值對於 switch 運算式具有明顯的意義,請為每個遺失比對的值新增一個 case

dart
enum E { one, two, three }

String f(E e) => switch (e) {
    E.one => 'one',
    E.two => 'two',
    E.three => 'three',
  };

如果遺失的值不需要比對,請新增一個萬用字元模式,以傳回簡單的預設值

dart
enum E { one, two, three }

String f(E e) => switch (e) {
    E.one => 'one',
    E.two => 'two',
    _ => 'unknown',
  };

請注意,萬用字元模式將處理未來新增至類型中的任何值。如果 switch 需要更新以考量新新增的類型,您將失去讓編譯器警告您的能力。

非詳盡的_switch_陳述式

#

類型「{0}」未被 switch case 完全比對,因為它與「{1}」不符。

描述

#

當針對窮舉類型進行 switch 切換的 switch 述句缺少一個或多個可能流經它的值的情況時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 switch 述句沒有值 E.three 的 case,且 E 是窮舉類型

dart
enum E { one, two, three }

void f(E e) {
  switch (e) {
    case E.one:
    case E.two:
  }
}

常見修正方式

#

請為每個目前未比對的常數新增一個 case

dart
enum E { one, two, three }

void f(E e) {
  switch (e) {
    case E.one:
    case E.two:
      break;
    case E.three:
  }
}

如果遺失的值不需要比對,請新增 default 子句或萬用字元模式

dart
enum E { one, two, three }

void f(E e) {
  switch (e) {
    case E.one:
    case E.two:
      break;
    default:
  }
}

但請注意,新增 default 子句或萬用字元模式將導致也處理窮舉類型的任何未來值,因此如果 switch 需要更新,您將失去讓編譯器警告您的能力。

列舉中非_final_欄位

#

列舉只能宣告 final 欄位。

描述

#

當列舉中的執行個體欄位未標記為 final 時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為欄位 f 不是 final 欄位

dart
enum E {
  c;

  int f = 0;
}

常見修正方式

#

如果欄位必須為列舉定義,請將欄位標記為 final

dart
enum E {
  c;

  final int f = 0;
}

如果可以移除欄位,請移除它

dart
enum E {
  c
}

非產生器建構子

#

預期的生成式建構子 '{0}',但找到工廠建構子。

描述

#

當建構子的初始化列表調用父類別的建構子,且調用的建構子是工廠建構子時,分析器會產生此診斷。只有生成式建構子可以在初始化列表中調用。

範例

#

下列程式碼會產生此診斷,因為建構子 super.one() 的調用正在調用工廠建構子

dart
class A {
  factory A.one() = B;
  A.two();
}

class B extends A {
  B() : super.one();
}

常見修正方式

#

請變更 super 調用以調用生成式建構子

dart
class A {
  factory A.one() = B;
  A.two();
}

class B extends A {
  B() : super.two();
}

如果生成式建構子是未命名的建構子,且如果沒有引數傳遞給它,則您可以移除 super 調用。

非產生器隱含建構子

#

父類別 '{0}' 的未命名建構子 (由 '{1}' 的預設建構子調用) 必須是生成式建構子,但找到工廠建構子。

描述

#

當類別具有隱含的生成式建構子,且父類別具有明確的未命名工廠建構子時,分析器會產生此診斷。子類別中的隱含建構子隱含地調用父類別中的未命名建構子,但生成式建構子只能調用另一個生成式建構子,而不能調用工廠建構子。

範例

#

下列程式碼會產生此診斷,因為 B 中的隱含建構子調用 A 中的未命名建構子,但 A 中的建構子是工廠建構子,而需要的是生成式建構子

dart
class A {
  factory A() => throw 0;
  A.named();
}

class B extends A {}

常見修正方式

#

如果父類別中的未命名建構子可以是生成式建構子,請將其變更為生成式建構子

dart
class A {
  A();
  A.named();
}

class B extends A { }

如果未命名建構子不能是生成式建構子,且父類別中還有其他生成式建構子,請明確調用其中一個

dart
class A {
  factory A() => throw 0;
  A.named();
}

class B extends A {
  B() : super.named();
}

如果沒有可用的生成式建構子,且無法新增任何建構子,請實作父類別而不是擴充它

dart
class A {
  factory A() => throw 0;
  A.named();
}

class B implements A {}

指標的非原生函式類型引數

#

無法調用 'asFunction',因為指標的函式簽章 '{0}' 不是有效的 C 函式簽章。

描述

#

當在原生函式的指標上調用方法 asFunction,但原生函式的簽章不是有效的 C 函式簽章時,分析器會產生此診斷。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

下列程式碼會產生此診斷,因為與指標 p 相關聯的函式簽章 (FNative) 不是有效的 C 函式簽章

dart
import 'dart:ffi';

typedef FNative = int Function(int);
typedef F = int Function(int);

class C {
  void f(Pointer<NativeFunction<FNative>> p) {
    p.asFunction<F>();
  }
}

常見修正方式

#

請將 NativeFunction 簽章設為有效的 C 簽章

dart
import 'dart:ffi';

typedef FNative = Int8 Function(Int8);
typedef F = int Function(int);

class C {
  void f(Pointer<NativeFunction<FNative>> p) {
    p.asFunction<F>();
  }
}

非正數陣列維度

#

陣列維度必須是正數。

描述

#

當在 Array 註解中給定的維度小於或等於零 (0) 時,分析器會產生此診斷。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

下列程式碼會產生此診斷,因為提供了 -8 的陣列維度

dart
import 'dart:ffi';

final class MyStruct extends Struct {
  @Array(-8)
  external Array<Uint8> a0;
}

常見修正方式

#

請將維度變更為正整數

dart
import 'dart:ffi';

final class MyStruct extends Struct {
  @Array(8)
  external Array<Uint8> a0;
}

如果這是可變長度內聯陣列,請將註解變更為 Array.variable()

dart
import 'dart:ffi';

final class MyStruct extends Struct {
  @Array.variable()
  external Array<Uint8> a0;
}

非尺寸類型引數

#

類型 '{1}' 不是 '{0}' 的有效型別引數。型別引數必須是原生整數、「Float」、「Double」、「Pointer」或「Struct」、「Union」或「AbiSpecificInteger」的子類型。

描述

#

當類別 Array 的型別引數不是有效類型之一時,分析器會產生此診斷:原生整數、FloatDoublePointerStructUnionAbiSpecificInteger 的子類型。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

下列程式碼會產生此診斷,因為 Array 的型別引數是 Void,而 Void 不是有效類型之一

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8)
  external Array<Void> a0;
}

常見修正方式

#

請將型別引數變更為有效類型之一

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8)
  external Array<Uint8> a0;
}

非同步_factory

#

工廠主體不能使用 'async'、'async*' 或 'sync*'。

描述

#

當工廠建構子的主體標記為 asyncasync*sync* 時,分析器會產生此診斷。所有建構子 (包括工廠建構子) 都必須傳回在其中宣告它們的類別的執行個體,而不是 FutureStreamIterator

範例

#

下列程式碼會產生此診斷,因為工廠建構子的主體標記為 async

dart
class C {
  factory C() async {
    return C._();
  }
  C._();
}

常見修正方式

#

如果成員必須宣告為工廠建構子,請移除出現在主體之前的關鍵字

dart
class C {
  factory C() {
    return C._();
  }
  C._();
}

如果成員必須傳回非封閉類別的執行個體,請將成員設為靜態方法

dart
class C {
  static Future<C> m() async {
    return C._();
  }
  C._();
}

非類型作為類型引數

#

名稱 '{0}' 不是類型,因此不能用作型別引數。

描述

#

當不是類型的識別碼被用作型別引數時,分析器會產生此診斷。

範例

#

以下程式碼產生此診斷訊息,因為 x 是一個變數,而不是型別。

dart
var x = 0;
List<x> xList = [];

常見修正方式

#

請將型別引數變更為類型

dart
var x = 0;
List<int> xList = [];

catch_子句中的非類型

#

名稱 '{0}' 不是類型,且不能在 on-catch 子句中使用。

描述

#

catch 子句中 on 後面的識別碼定義為類型以外的其他內容時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 f 是函式,而不是類型

dart
void f() {
  try {
    // ...
  } on f {
    // ...
  }
}

常見修正方式

#

請將名稱變更為應捕捉的物件的類型

dart
void f() {
  try {
    // ...
  } on FormatException {
    // ...
  }
}

運算子的非_void傳回

#

運算子 []= 的傳回類型必須是 'void'。

描述

#

當運算子 []= 的宣告具有 void 以外的傳回類型時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為運算子 []= 的宣告具有 int 的傳回類型

dart
class C {
  int operator []=(int index, int value) => 0;
}

常見修正方式

#

請將傳回類型變更為 void

dart
class C {
  void operator []=(int index, int value) => 0;
}

setter的非_void傳回

#

setter 的傳回類型必須是 'void' 或不存在。

描述

#

當 setter 定義為 void 以外的傳回類型時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 setter p 的傳回類型為 int

dart
class C {
  int set p(int i) => 0;
}

常見修正方式

#

請將傳回類型變更為 void 或省略傳回類型

dart
class C {
  set p(int i) => 0;
}

未賦值的潛在非可為 Null 區域變數

#

不可為 Null 的區域變數 '{0}' 必須在使用前指派值。

描述

#

當區域變數被參照且具有以下所有特性時,分析器會產生此診斷

  • 具有潛在不可為 Null的類型。
  • 沒有初始化子。
  • 未標記為 late
  • 根據明確賦值的規範,分析器無法證明區域變數會在參照之前被指派值。

範例

#

下列程式碼會產生此診斷,因為 x 不能具有 null 值,但在指派值之前被參照

dart
String f() {
  int x;
  return x.toString();
}

下列程式碼會產生此診斷,因為對 x 的指派可能未執行,因此它可能具有 null

dart
int g(bool b) {
  int x;
  if (b) {
    x = 1;
  }
  return x * 2;
}

下列程式碼會產生此診斷,因為根據明確賦值分析,分析器無法證明 x 不會在未指派值的情況下被參照

dart
int h(bool b) {
  int x;
  if (b) {
    x = 1;
  }
  if (b) {
    return x * 2;
  }
  return 0;
}

常見修正方式

#

如果 null 是有效值,請使變數可為 Null

dart
String f() {
  int? x;
  return x!.toString();
}

如果 null 不是有效值,且有合理的預設值,請新增初始化子

dart
int g(bool b) {
  int x = 2;
  if (b) {
    x = 1;
  }
  return x * 2;
}

否則,請確保在存取值之前,在每個可能的程式碼路徑上都已指派值

dart
int g(bool b) {
  int x;
  if (b) {
    x = 1;
  } else {
    x = 2;
  }
  return x * 2;
}

您也可以將變數標記為 late,這會移除診斷,但如果變數在存取之前未指派值,則會在執行時期導致擲回例外狀況。只有當您確定變數始終會被指派值時,才應使用此方法,即使分析器無法根據明確賦值分析證明這一點。

dart
int h(bool b) {
  late int x;
  if (b) {
    x = 1;
  }
  if (b) {
    return x * 2;
  }
  return 0;
}

不是類型

#

{0} 不是類型。

描述

#

當名稱用作類型,但宣告為類型以外的其他內容時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 f 是函式

dart
f() {}
g(f v) {}

常見修正方式

#

請將名稱替換為類型的名稱。

不是二元運算子

#

'{0}' 不是二元運算子。

描述

#

當只能用作一元運算子的運算子被用作二元運算子時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為運算子 ~ 只能用作一元運算子

dart
var a = 5 ~ 3;

常見修正方式

#

請將運算子替換為正確的二元運算子

dart
var a = 5 - 3;

位置引數不足

#

'{0}' 預期 1 個位置引數,但找到 0 個。

預期 1 個位置引數,但找到 0 個。

'{2}' 預期 {0} 個位置引數,但找到 {1} 個。

預期 {0} 個位置引數,但找到 {1} 個。

描述

#

當方法或函式調用具有的位置引數少於所需位置參數的數量時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 f 宣告了兩個必要參數,但僅提供了一個引數

dart
void f(int a, int b) {}
void g() {
  f(0);
}

常見修正方式

#

請新增與剩餘參數對應的引數

dart
void f(int a, int b) {}
void g() {
  f(0, 1);
}

未初始化的非可為 Null 實例欄位

#

不可為 Null 的執行個體欄位 '{0}' 必須初始化。

描述

#

當宣告欄位且具有以下所有特性時,分析器會產生此診斷

範例

#

下列程式碼會產生此診斷,因為 x 在不允許為 null 時隱含地初始化為 null

dart
class C {
  int x;
}

同樣地,下列程式碼會產生此診斷,因為 x 在不允許為 null 時,被其中一個建構子隱含地初始化為 null,即使它被其他建構子初始化也是如此

dart
class C {
  int x;

  C(this.x);

  C.n();
}

常見修正方式

#

如果欄位存在適用於所有執行個體的合理預設值,請新增初始化運算式

dart
class C {
  int x = 0;
}

如果欄位的值應在建立執行個體時提供,請新增一個設定欄位值的建構子,或更新現有的建構子

dart
class C {
  int x;

  C(this.x);
}

您也可以將欄位標記為 late,這會移除診斷,但如果欄位在存取之前未指派值,則會在執行時期導致擲回例外狀況。只有當您確定欄位始終會在被參照之前指派值時,才應使用此方法。

dart
class C {
  late int x;
}

未初始化的非可為 Null 變數

#

不可為 Null 的變數 '{0}' 必須初始化。

描述

#

當靜態欄位或頂層變數具有不可為 Null 的類型且沒有初始化子時,分析器會產生此診斷。沒有初始化子的欄位和變數通常會初始化為 null,但欄位或變數的類型不允許將其設定為 null,因此必須提供明確的初始化子。

範例

#

下列程式碼會產生此診斷,因為欄位 f 無法初始化為 null

dart
class C {
  static int f;
}

同樣地,下列程式碼會產生此診斷,因為頂層變數 v 無法初始化為 null

dart
int v;

常見修正方式

#

如果欄位或變數無法初始化為 null,請新增一個將其設定為不可為 Null 值的初始化子

dart
class C {
  static int f = 0;
}

如果欄位或變數應初始化為 null,請將類型變更為可為 Null

dart
int? v;

如果欄位或變數無法在宣告中初始化,但始終會在被參照之前初始化,請將其標記為 late

dart
class C {
  static late int f;
}

非可迭代的展開

#

列表或集合常值中的展開元素必須實作 'Iterable'。

描述

#

當出現在列表常值或集合常值中的展開元素的靜態類型未實作類型 Iterable 時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷訊息

dart
var m = <String, int>{'a': 0, 'b': 1};
var s = <String>{...m};

常見修正方式

#

最常見的修正方法是用產生可迭代物件的運算式替換運算式

dart
var m = <String, int>{'a': 0, 'b': 1};
var s = <String>{...m.keys};

非_map_展開

#

映射常值中的展開元素必須實作 'Map'。

描述

#

當出現在映射常值中的展開元素的靜態類型未實作類型 Map 時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 l 不是 Map

dart
var l =  <String>['a', 'b'];
var m = <int, String>{...l};

常見修正方式

#

最常見的修正方法是用產生映射的運算式替換運算式

dart
var l =  <String>['a', 'b'];
var m = <int, String>{...l.asMap()};

沒有註解建構子引數

#

註解建立必須具有引數。

描述

#

當註解由單一識別碼組成,但該識別碼是類別名稱而不是變數名稱時,分析器會產生此診斷。若要建立類別的執行個體,識別碼後面必須跟著引數列表。

範例

#

下列程式碼會產生此診斷,因為 C 是類別,而類別不能用作註解,除非從類別調用 const 建構子

dart
class C {
  const C();
}

@C
var x;

常見修正方式

#

請新增遺失的引數列表

dart
class C {
  const C();
}

@C()
var x;

沒有組合的_super_簽章

#

無法從覆寫的方法:{1},在 '{0}' 中推論遺失的類型。

描述

#

當存在方法宣告,其中一個或多個類型需要推論,且這些類型無法推論,因為根據覆寫推論的規範,沒有任何覆寫方法的函式類型是所有其他覆寫方法的超類型時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為在類別 C 中宣告的方法 m 遺失了傳回類型和參數 a 的類型,且這兩個遺失的類型都無法為其推論

dart
abstract class A {
  A m(String a);
}

abstract class B {
  B m(int a);
}

abstract class C implements A, B {
  m(a);
}

在此範例中,無法執行覆寫推論,因為覆寫的方法在以下方面不相容

  • 參數類型 (Stringint) 皆不是對方的超類型。
  • 傳回類型皆不是對方的子類型。

常見修正方式

#

如果可能,請將與所有覆寫方法中的類型一致的類型新增至子類別中的方法

dart
abstract class A {
  A m(String a);
}

abstract class B {
  B m(int a);
}

abstract class C implements A, B {
  C m(Object a);
}

父類別中沒有產生器建構子

#

類別 '{0}' 無法擴充 '{1}',因為 '{1}' 只有工廠建構子 (沒有生成式建構子),且 '{0}' 至少有一個生成式建構子。

描述

#

當至少有一個生成式建構子 (無論是明確或隱含) 的類別具有沒有任何生成式建構子的父類別時,分析器會產生此診斷。每個生成式建構子 (Object 中定義的建構子除外) 都會明確或隱含地調用其父類別中的生成式建構子之一。

範例

#

下列程式碼會產生此診斷,因為類別 B 具有隱含的生成式建構子,該建構子無法調用 A 中的生成式建構子,因為 A 沒有任何生成式建構子

dart
class A {
  factory A.none() => throw '';
}

class B extends A {}

常見修正方式

#

如果父類別應具有生成式建構子,請新增一個

dart
class A {
  A();
  factory A.none() => throw '';
}

class B extends A {}

如果子類別不應具有生成式建構子,請透過新增工廠建構子來移除它

dart
class A {
  factory A.none() => throw '';
}

class B extends A {
  factory B.none() => throw '';
}

如果子類別必須具有生成式建構子,但父類別不能有,請實作父類別而不是擴充它

dart
class A {
  factory A.none() => throw '';
}

class B implements A {}

catch_子句中的可為 Null 類型

#

潛在可為 Null 的類型不能在 'on' 子句中使用,因為擲回可為 Null 的運算式是無效的。

描述

#

catch 子句中 on 後面的類型是可為 Null 的類型時,分析器會產生此診斷。指定可為 Null 的類型是無效的,因為捕捉 null 是不可能的 (因為擲回 null 是執行時期錯誤)。

範例

#

下列程式碼會產生此診斷,因為指定的例外狀況類型允許 null,但 null 無法被擲回

dart
void f() {
  try {
    // ...
  } on FormatException? {
  }
}

常見修正方式

#

請從類型中移除問號

dart
void f() {
  try {
    // ...
  } on FormatException {
  }
}

extends_子句中的可為 Null 類型

#

類別無法擴充可為 Null 的類型。

描述

#

當類別宣告使用 extends 子句來指定父類別,且父類別後面跟著 ? 時,分析器會產生此診斷。

指定可為 Null 的父類別是無效的,因為這樣做沒有意義;它不會變更包含 extends 子句的類別所繼承的介面或實作。

但請注意,將可為 Null 的類型用作父類別的型別引數是有效的,例如 class A extends B<C?> {}

範例

#

下列程式碼會產生此診斷,因為 A? 是可為 Null 的類型,且可為 Null 的類型不能在 extends 子句中使用

dart
class A {}
class B extends A? {}

常見修正方式

#

請從類型中移除問號

dart
class A {}
class B extends A {}

implements_子句中的可為 Null 類型

#

類別、mixin 或擴充型別無法實作可為 Null 的類型。

描述

#

當類別、mixin 或擴充型別宣告具有 implements 子句,且介面後面跟著 ? 時,分析器會產生此診斷。

指定可為 Null 的介面是無效的,因為這樣做沒有意義;它不會變更包含 implements 子句的類別所繼承的介面。

但請注意,將可為 Null 的類型用作介面的型別引數是有效的,例如 class A implements B<C?> {}

範例

#

下列程式碼會產生此診斷,因為 A? 是可為 Null 的類型,且可為 Null 的類型不能在 implements 子句中使用

dart
class A {}
class B implements A? {}

常見修正方式

#

請從類型中移除問號

dart
class A {}
class B implements A {}

on_子句中的可為 Null 類型

#

mixin 不能將可為 Null 的類型作為父類別約束。

描述

#

當 mixin 宣告使用 on 子句來指定父類別約束,且指定的類別後面跟著 ? 時,分析器會產生此診斷。

指定可為 Null 的父類別約束是無效的,因為這樣做沒有意義;它不會變更包含 on 子句的 mixin 所依賴的介面。

但請注意,將可為 Null 的類型用作父類別約束的型別引數是有效的,例如 mixin A on B<C?> {}

範例

#

下列程式碼會產生此診斷,因為 A? 是可為 Null 的類型,且可為 Null 的類型不能在 on 子句中使用

dart
class C {}
mixin M on C? {}

常見修正方式

#

請從類型中移除問號

dart
class C {}
mixin M on C {}

with_子句中的可為 Null 類型

#

類別或 mixin 無法混入可為 Null 的類型。

描述

#

當類別或 mixin 宣告具有 with 子句,且 mixin 後面跟著 ? 時,分析器會產生此診斷。

指定可為 Null 的 mixin 是無效的,因為這樣做沒有意義;它不會變更包含 with 子句的類別所繼承的介面或實作。

但請注意,將可為 Null 的類型用作 mixin 的型別引數是有效的,例如 class A with B<C?> {}

範例

#

下列程式碼會產生此診斷,因為 A? 是可為 Null 的類型,且可為 Null 的類型不能在 with 子句中使用

dart
mixin M {}
class C with M? {}

常見修正方式

#

請從類型中移除問號

dart
mixin M {}
class C with M {}

null引數給非_null類型

#

不應使用 'null' 引數調用 '{0}' 作為不可為 Null 的型別引數 '{1}'。

描述

#

null 傳遞給建構子 Future.value 或方法 Completer.complete 時,如果用於建立執行個體的型別引數是不可為 Null 的,則分析器會產生此診斷。即使類型系統無法表達此限制,傳入 null 也會導致執行時期例外狀況。

範例

#

下列程式碼會產生此診斷,因為 null 正傳遞給建構子 Future.value,即使型別引數是不可為 Null 的類型 String 也是如此

dart
Future<String> f() {
  return Future.value(null);
}

常見修正方式

#

請傳入不可為 Null 的值

dart
Future<String> f() {
  return Future.value('');
}

null檢查永遠失敗

#

此 null 檢查將始終擲回例外狀況,因為運算式將始終評估為 'null'。

描述

#

當 null 檢查運算子 (!) 用於值只能是 null 的運算式時,分析器會產生此診斷。在這種情況下,運算子始終會擲回例外狀況,這可能不是預期的行為。

範例

#

下列程式碼會產生此診斷,因為函式 g 將始終傳回 null,這表示 f 中的 null 檢查將始終擲回例外狀況

dart
void f() {
  g()!;
}

Null g() => null;

常見修正方式

#

如果您打算始終擲回例外狀況,請將 null 檢查替換為明確的 throw 運算式,以使意圖更明確

dart
void f() {
  g();
  throw TypeError();
}

Null g() => null;

已過時的冒號作為預設值

#

不再支援在預設值之前使用冒號作為分隔符號。

描述

#

當冒號 (:) 用作選用具名參數的預設值之前的分隔符號時,分析器會產生此診斷。雖然過去允許此語法,但已將其移除,改為使用等號 (=)。

範例

#

以下程式碼會產生此診斷,因為在選用參數 i 的預設值之前使用了冒號

dart
void f({int i : 0}) {}

常見修正方式

#

請將冒號替換為等號

dart
void f({int i = 0}) {}

on重複

#

類型 '{0}' 只能在父類別約束中包含一次。

描述

#

當相同的類型在 mixin 的父類別約束中多次列出時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 AM 的父類別約束中包含兩次

dart
mixin M on A, A {
}

class A {}
class B {}

常見修正方式

#

如果應在父類別約束中包含不同的類型,請將其中一個出現次數替換為另一個類型

dart
mixin M on A, B {
}

class A {}
class B {}

如果沒有預期其他類型,請移除重複的類型名稱

dart
mixin M on A {
}

class A {}
class B {}

運算子中的選用參數

#

定義運算子時不允許選用參數。

描述

#

當運算子宣告中的一個或多個參數是選用參數時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為參數 other 是選用參數

dart
class C {
  C operator +([C? other]) => this;
}

常見修正方式

#

請使所有參數成為必要參數

dart
class C {
  C operator +(C other) => this;
}

非覆寫成員的覆寫

#

欄位未覆寫繼承的 getter 或 setter。

getter 未覆寫繼承的 getter。

方法未覆寫繼承的方法。

setter 未覆寫繼承的 setter。

描述

#

當類別成員使用 @override 註解標註,但該成員未在類別的任何父類型中宣告時,分析器會產生此診斷。

範例

#

下列程式碼會產生此診斷,因為 m 未在 C 的任何父類型中宣告

dart
class C {
  @override
  String m() => '';
}

常見修正方式

#

如果成員旨在覆寫名稱不同的成員,請更新成員以具有相同的名稱

dart
class C {
  @override
  String toString() => '';
}

如果成員旨在覆寫已從父類別中移除的成員,請考慮從子類別中移除成員。

如果無法移除成員,請移除註解。

packed註解

#

Structs 必須最多有一個 'Packed' 註解。

描述

#

Struct 的子類別具有多個 Packed 註解時,分析器會產生此診斷。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

下列程式碼會產生此診斷,因為類別 C (Struct 的子類別) 具有兩個 Packed 註解

dart
import 'dart:ffi';

@Packed(1)
@Packed(1)
final class C extends Struct {
  external Pointer<Uint8> notEmpty;
}

常見修正方式

#

移除除了其中一個註解之外的所有註解

dart
import 'dart:ffi';

@Packed(1)
final class C extends Struct {
  external Pointer<Uint8> notEmpty;
}

packed註解對齊

#

僅支援封裝為 1、2、4、8 和 16 個位元組。

描述

#

Packed 註解的引數不是允許的值之一時:1、2、4、8 或 16,分析器會產生此診斷。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

下列程式碼會產生此診斷,因為 Packed 註解的引數 (3) 不是允許的值之一

dart
import 'dart:ffi';

@Packed(3)
final class C extends Struct {
  external Pointer<Uint8> notEmpty;
}

常見修正方式

#

請將對齊方式變更為允許的值之一

dart
import 'dart:ffi';

@Packed(4)
final class C extends Struct {
  external Pointer<Uint8> notEmpty;
}

不同程式庫的_part_of

#

預期此函式庫是 '{0}' 的一部分,而不是 '{1}'。

描述

#

當函式庫嘗試將檔案作為自身的一部分包含時,如果另一個檔案是不同函式庫的一部分,則分析器會產生此診斷。

範例

#

給定一個包含以下內容的檔案 part.dart

dart
part of 'library.dart';

下列程式碼 (在 library.dart 以外的任何檔案中) 會產生此診斷,因為它嘗試將 part.dart 作為自身的一部分包含,而 part.dart 是不同函式庫的一部分

dart
part 'package:a/part.dart';

常見修正方式

#

如果函式庫應使用不同的檔案作為一部分,請將 part 指示詞中的 URI 變更為另一個檔案的 URI。

如果part 檔案應為此函式庫的一部分,請更新 part-of 指示詞中的 URI (或函式庫名稱) 以成為正確函式庫的 URI (或名稱)。

非_part的_part_of

#

包含的 part '{0}' 必須具有 part-of 指示詞。

描述

#

當找到 part 指示詞,且參照的檔案沒有 part-of 指示詞時,分析器會產生此診斷。

範例

#

假設檔案 a.dart 包含

dart
class A {}

下列程式碼會產生此診斷,因為 a.dart 不包含 part-of 指示詞

dart
part 'a.dart';

常見修正方式

#

如果參照的檔案旨在成為另一個函式庫的一部分,請將 part-of 指示詞新增至檔案

dart
part of 'test.dart';

class A {}

如果參考的檔案旨在作為一個程式庫,則將 part 指令替換為 import 指令

dart
import 'a.dart';

未命名程式庫的_part_of

#

程式庫未命名。在 part-of 指令中,預期的是 URI,而不是程式庫名稱 '{0}'。

描述

#

當一個沒有 library 指令(因此沒有名稱)的程式庫包含 part 指令,且部分檔案中的 part of 指令使用名稱來指定它所屬的程式庫時,分析器會產生此診斷訊息。

範例

#

假設一個名為 part_file.dart部分檔案包含以下程式碼

dart
part of lib;

以下程式碼產生此診斷訊息,因為包含部分檔案的程式庫沒有名稱,即使部分檔案使用名稱來指定它所屬的程式庫

dart
part 'part_file.dart';

常見修正方式

#

變更部分檔案中的 part of 指令,以 URI 指定其程式庫

dart
part of 'test.dart';

路徑不存在

#

路徑 '{0}' 不存在。

描述

#

當相依性具有 path 鍵,且該鍵參考到一個不存在的目錄時,分析器會產生此診斷訊息。

範例

#

假設目錄 doesNotExist 不存在,以下程式碼會產生此診斷訊息,因為它被列為套件的路徑

yaml
name: example
dependencies:
  local_package:
    path: doesNotExist

常見修正方式

#

如果路徑正確,則在該路徑建立一個目錄。

如果路徑不正確,則變更路徑以符合套件根目錄的路徑。

路徑不是_POSIX

#

路徑 '{0}' 不是 POSIX 樣式的路徑。

描述

#

當相依性具有 path 鍵,且其值為字串,但不是 POSIX 樣式的路徑時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 path 鍵後面的路徑是 Windows 路徑

yaml
name: example
dependencies:
  local_package:
    path: E:\local_package

常見修正方式

#

將路徑轉換為 POSIX 路徑。

路徑_pubspec不存在

#

目錄 '{0}' 不包含 pubspec。

描述

#

當相依性具有 path 鍵,且該鍵參考到一個不包含 pubspec.yaml 檔案的目錄時,分析器會產生此診斷訊息。

範例

#

假設目錄 local_package 不包含檔案 pubspec.yaml,以下程式碼會產生此診斷訊息,因為它被列為套件的路徑

yaml
name: example
dependencies:
  local_package:
    path: local_package

常見修正方式

#

如果路徑旨在作為套件的根目錄,則在目錄中新增 pubspec.yaml 檔案

yaml
name: local_package

如果路徑錯誤,則將其替換為正確的路徑。

模式賦值不是區域變數

#

模式賦值中只能賦值給區域變數。

描述

#

當模式賦值將值賦值給區域變數以外的任何項目時,分析器會產生此診斷訊息。模式無法賦值給欄位或頂層變數。

範例

#

如果使用模式解構程式碼更簡潔,則重寫程式碼以在模式宣告中將值賦值給區域變數,並單獨賦值給非區域變數

dart
class C {
  var x = 0;

  void f((int, int) r) {
    (x, _) = r;
  }
}

常見修正方式

#

如果使用模式賦值程式碼更簡潔,則重寫程式碼以將值賦值給區域變數,並單獨賦值給非區域變數

dart
class C {
  var x = 0;

  void f((int, int) r) {
    var (a, _) = r;
    x = a;
  }
}

如果未使用模式賦值程式碼更簡潔,則重寫程式碼以不使用模式賦值

dart
class C {
  var x = 0;

  void f((int, int) r) {
    x = r.$1;
  }
}

來自延遲載入程式庫的模式常數

#

延遲程式庫中的常數值無法在模式中使用。

描述

#

當模式包含在不同程式庫中宣告的值,且該程式庫是使用延遲匯入來匯入時,分析器會產生此診斷訊息。常數在編譯時評估,但延遲程式庫中的值在編譯時不可用。

有關更多資訊,請查看 延遲載入程式庫

範例

#

給定一個檔案 a.dart,它定義了常數 zero

dart
const zero = 0;

以下程式碼會產生此診斷訊息,因為常數模式 a.zero 是使用延遲匯入來匯入的

dart
import 'a.dart' deferred as a;

void f(int x) {
  switch (x) {
    case a.zero:
      // ...
      break;
  }
}

常見修正方式

#

如果您需要參照匯入函式庫中的常數,請移除 deferred 關鍵字

dart
import 'a.dart' as a;

void f(int x) {
  switch (x) {
    case a.zero:
      // ...
      break;
  }
}

如果您需要參照匯入函式庫中的常數,且也需要延遲匯入該函式庫,請將 switch 述句改寫為一連串的 if 述句

dart
import 'a.dart' deferred as a;

void f(int x) {
  if (x == a.zero) {
    // ...
  }
}

如果您不需要參照常數,請替換 case 運算式

dart
void f(int x) {
  switch (x) {
    case 0:
      // ...
      break;
  }
}

不可反駁情境中的模式類型不符

#

類型為 '{0}' 的比對值無法賦值給所需的類型 '{1}'。

描述

#

當模式賦值或模式宣告右側的值的類型,與用於比對它的模式所需類型不符時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 x 可能不是 String,因此可能不符合物件模式

dart
void f(Object x) {
  var String(length: a) = x;
  print(a);
}

常見修正方式

#

變更程式碼,使右側運算式的類型符合模式所需的類型

dart
void f(String x) {
  var String(length: a) = x;
  print(a);
}

防護中的模式變數賦值

#

模式變數無法在封閉的受保護模式的 guard 內部賦值。

描述

#

當模式變數在 guard (when) 子句內部被賦值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為變數 a 在 guard 子句內部被賦值

dart
void f(int x) {
  if (x case var a when (a = 1) > 0) {
    print(a);
  }
}

常見修正方式

#

如果有一個您需要捕獲的值,則將其賦值給不同的變數

dart
void f(int x) {
  var b;
  if (x case var a when (b = 1) > 0) {
    print(a + b);
  }
}

如果沒有您需要捕獲的值,則移除賦值

dart
void f(int x) {
  if (x case var a when 1 > 0) {
    print(a);
  }
}

不允許的平台值

#

platforms 欄位中的鍵不能有值。

描述

#

platforms 映射中的鍵具有值時,分析器會產生此診斷訊息。若要深入瞭解如何指定您的套件支援的平台,請查看關於平台宣告的文件

範例

#

以下 pubspec.yaml 會產生此診斷訊息,因為鍵 web 具有值。

yaml
name: example
platforms:
  web: "chrome"

常見修正方式

#

省略值並讓鍵沒有值

yaml
name: example
platforms:
  web:

platforms 欄位中鍵的值目前保留供未來可能的行為使用。

物件模式中的位置欄位

#

物件模式只能使用具名字段。

描述

#

當物件模式包含一個欄位,但未指定 getter 名稱時,分析器會產生此診斷訊息。物件模式欄位會比對物件的 getter 回傳的值。在未指定 getter 名稱的情況下,模式欄位無法存取值以嘗試比對。

範例

#

以下程式碼會產生此診斷訊息,因為物件模式 String(1) 未指定要存取 String 的哪個 getter 並與值 1 比較

dart
void f(Object o) {
  if (o case String(1)) {}
}

常見修正方式

#

新增 getter 名稱以存取值,然後在要比對的模式之前加上冒號

dart
void f(Object o) {
  if (o case String(length: 1)) {}
}

具有位置引數的位置_super_形式參數

#

當 super 建構子調用具有位置引數時,不能使用位置 super 參數。

描述

#

當提供給超類別建構子的某些(但非全部)位置參數使用 super 參數時,分析器會產生此診斷訊息。

位置 super 參數透過索引與 super 建構子中的位置參數相關聯。也就是說,第一個 super 參數與 super 建構子中的第一個位置參數相關聯,第二個與第二個相關聯,依此類推。位置引數也是如此。同時具有位置 super 參數和位置引數表示有兩個值與超類別建構子中的同一個參數相關聯,因此不允許這樣做。

範例

#

以下程式碼會產生此診斷訊息,因為建構子 B.new 正在使用 super 參數將其中一個必要的位置參數傳遞給 A 中的 super 建構子,但正在 super 建構子調用中明確傳遞另一個參數

dart
class A {
  A(int x, int y);
}

class B extends A {
  B(int x, super.y) : super(x);
}

常見修正方式

#

如果所有位置參數都可以是 super 參數,則將正常的位置參數轉換為 super 參數

dart
class A {
  A(int x, int y);
}

class B extends A {
  B(super.x, super.y);
}

如果某些位置參數不能是 super 參數,則將 super 參數轉換為正常參數

dart
class A {
  A(int x, int y);
}

class B extends A {
  B(int x, int y) : super(x, y);
}

前置詞與最上層成員衝突

#

名稱 '{0}' 已用作匯入前綴,不能用於命名頂層元素。

描述

#

當一個名稱同時用作匯入前綴和同一個程式庫中頂層宣告的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 同時用作匯入前綴和函式的名稱

dart
import 'dart:math' as f;

int f() => f.min(0, 1);

常見修正方式

#

如果您想將該名稱用於匯入前綴,則重新命名頂層宣告

dart
import 'dart:math' as f;

int g() => f.min(0, 1);

如果您想將該名稱用於頂層宣告,則重新命名匯入前綴

dart
import 'dart:math' as math;

int f() => math.min(0, 1);

前置詞識別項後面沒有點

#

名稱 '{0}' 指的是匯入前綴,因此後面必須加上 '.'。

描述

#

當匯入前綴單獨使用,而沒有存取與前綴相關聯的程式庫中宣告的任何名稱時,分析器會產生此診斷訊息。前綴不是變數,因此不能用作值。

範例

#

以下程式碼會產生此診斷訊息,因為前綴 math 被當作變數使用

dart
import 'dart:math' as math;

void f() {
  print(math);
}

常見修正方式

#

如果程式碼不完整,則參考與前綴相關聯的其中一個程式庫中的內容

dart
import 'dart:math' as math;

void f() {
  print(math.pi);
}

如果名稱錯誤,則更正名稱。

本機宣告遮蔽的前置詞

#

前綴 '{0}' 無法在此處使用,因為它被區域宣告遮蔽。

描述

#

當匯入前綴在一個上下文中使用,但由於被區域宣告遮蔽而不可見時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為前綴 a 用於存取類別 Future,但由於它被參數 a 遮蔽而不可見

dart
import 'dart:async' as a;

a.Future? f(int a) {
  a.Future? x;
  return x;
}

常見修正方式

#

重新命名前綴

dart
import 'dart:async' as p;

p.Future? f(int a) {
  p.Future? x;
  return x;
}

或重新命名區域變數

dart
import 'dart:async' as a;

a.Future? f(int p) {
  a.Future? x;
  return x;
}

mixin應用中的私有衝突

#

由 '{1}' 定義的私有名稱 '{0}' 與由 '{2}' 定義的同名衝突。

描述

#

當兩個 mixin 定義相同的私有成員,且在定義 mixin 之外的程式庫中的單一類別中一起使用時,分析器會產生此診斷訊息。

範例

#

假設一個名為 a.dart 的檔案包含以下程式碼

dart
mixin A {
  void _foo() {}
}

mixin B {
  void _foo() {}
}

以下程式碼會產生此診斷訊息,因為 mixin AB 都定義了方法 _foo

dart
import 'a.dart';

class C extends Object with A, B {}

常見修正方式

#

如果您不需要兩個 mixin,則從 with 子句中移除其中一個

dart
import 'a.dart';

class C extends Object with A, B {}

如果您需要兩個 mixin,則重新命名兩個 mixin 之一中衝突的成員。

私有選用參數

#

具名參數不能以下底線開頭。

描述

#

當具名參數的名稱以下底線開頭時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為具名參數 _x 以下底線開頭

dart
class C {
  void m({int _x = 0}) {}
}

常見修正方式

#

重新命名參數,使其不以下底線開頭

dart
class C {
  void m({int x = 0}) {}
}

私有_setter

#

setter '{0}' 是私有的,無法在宣告它的程式庫外部存取。

描述

#

當私有 setter 在一個它不可見的程式庫中使用時,分析器會產生此診斷訊息。

範例

#

給定一個包含以下內容的檔案 a.dart

dart
class A {
  static int _f = 0;
}

以下程式碼會產生此診斷訊息,因為它參考了私有 setter _f,即使該 setter 不可見

dart
import 'a.dart';

void f() {
  A._f = 0;
}

常見修正方式

#

如果您可以將 setter 設為公開,則這樣做

dart
class A {
  static int f = 0;
}

如果您無法將 setter 設為公開,則尋找不同的方式來實作程式碼。

讀取可能未賦值的_final

#

final 變數 '{0}' 無法讀取,因為它在此時可能尚未賦值。

描述

#

當在宣告位置未初始化的 final 區域變數,在編譯器無法證明該變數在被參考之前總是已初始化的點被讀取時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 final 區域變數 x 在讀取時(第 3 行)可能尚未初始化

dart
int f() {
  final int x;
  return x;
}

常見修正方式

#

確保變數在讀取之前已初始化

dart
int f(bool b) {
  final int x;
  if (b) {
    x = 0;
  } else {
    x = 1;
  }
  return x;
}

記錄字面值一個位置沒有尾隨逗號

#

只有一個位置欄位的記錄字面值需要尾隨逗號。

描述

#

當只有單一位置欄位的記錄字面值在欄位後方沒有尾隨逗號時,分析器會產生此診斷訊息。

在某些位置,只有單一位置欄位的記錄字面值也可能是括號括住的運算式。需要尾隨逗號來消除這兩種有效解釋的歧義。

範例

#

以下程式碼會產生此診斷訊息,因為記錄字面值有一個位置欄位,但沒有尾隨逗號

dart
var r = const (1);

常見修正方式

#

新增尾隨逗號

dart
var r = const (1,);

記錄類型一個位置沒有尾隨逗號

#

只有一個位置欄位的記錄類型需要尾隨逗號。

描述

#

當只有單一位置欄位的記錄類型註解在欄位後方沒有尾隨逗號時,分析器會產生此診斷訊息。

在某些位置,只有單一位置欄位的記錄類型也可能是括號括住的運算式。需要尾隨逗號來消除這兩種有效解釋的歧義。

範例

#

以下程式碼會產生此診斷訊息,因為記錄類型有一個位置欄位,但沒有尾隨逗號

dart
void f((int) r) {}

常見修正方式

#

新增尾隨逗號

dart
void f((int,) r) {}

遞迴編譯時期常數

#

編譯時期常數運算式依賴自身。

描述

#

當編譯時期常數的值根據自身定義時(直接或間接),會產生無限迴圈,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生兩次此診斷訊息,因為兩個常數都是根據另一個常數定義的

dart
const secondsPerHour = minutesPerHour * 60;
const minutesPerHour = secondsPerHour / 60;

常見修正方式

#

透過尋找至少一種常數的替代定義方式來打破循環

dart
const secondsPerHour = minutesPerHour * 60;
const minutesPerHour = 60;

遞迴建構子重新導向

#

建構子無法直接或間接地重新導向自身。

描述

#

當建構子直接或間接地重新導向自身時,會產生無限迴圈,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為產生器建構子 C.aC.b 各自重新導向另一個

dart
class C {
  C.a() : this.b();
  C.b() : this.a();
}

以下程式碼會產生此診斷訊息,因為工廠建構子 AB 各自重新導向另一個

dart
abstract class A {
  factory A() = B;
}
class B implements A {
  factory B() = A;
  B.named();
}

常見修正方式

#

在產生器建構子的情況下,透過定義至少一個不重新導向至另一個建構子的建構子來打破循環

dart
class C {
  C.a() : this.b();
  C.b();
}

在工廠建構子的情況下,透過定義至少一個工廠建構子來打破循環,使其執行以下操作之一

  • 重新導向至產生器建構子
dart
abstract class A {
  factory A() = B;
}
class B implements A {
  factory B() = B.named;
  B.named();
}
  • 不重新導向至另一個建構子
dart
abstract class A {
  factory A() = B;
}
class B implements A {
  factory B() {
    return B.named();
  }

  B.named();
}
  • 不是工廠建構子
dart
abstract class A {
  factory A() = B;
}
class B implements A {
  B();
  B.named();
}

遞迴介面繼承

#

'{0}' 不能是自身的超介面:{1}。

'{0}' 不能擴充自身。

'{0}' 不能實作自身。

'{0}' 不能將自身用作 mixin。

'{0}' 不能將自身用作超類別約束。

描述

#

當類型階層中存在循環性時,分析器會產生此診斷訊息。當一個類型直接或間接地宣告為自身的子類型時,就會發生這種情況。

範例

#

以下程式碼會產生此診斷訊息,因為類別 A 宣告為 B 的子類型,而 BA 的子類型

dart
class A extends B {}
class B implements A {}

常見修正方式

#

變更類型階層,使其沒有循環性。

非重新宣告成員的重新宣告

#

{0} 未重新宣告超介面中宣告的 {0}。

描述

#

當擴充功能類型的成員使用 @redeclare 註解,但已實作的介面中沒有任何成員具有相同名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充功能類型 E 宣告的成員 n 使用了 @redeclare 註解,但 C 沒有名為 n 的成員

dart
import 'package:meta/meta.dart';

class C {
  void m() {}
}

extension type E(C c) implements C {
  @redeclare
  void n() {}
}

常見修正方式

#

如果註解的成員名稱正確,則移除註解

dart
class C {
  void m() {}
}

extension type E(C c) implements C {
  void n() {}
}

如果註解的成員應該取代已實作介面中的成員,則變更註解成員的名稱以符合要取代的成員

dart
import 'package:meta/meta.dart';

class C {
  void m() {}
}

extension type E(C c) implements C {
  @redeclare
  void m() {}
}

重新導向產生器至遺失的建構子

#

在 '{1}' 中找不到建構子 '{0}'。

描述

#

當產生器建構子重新導向至未定義的建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為建構子 C.a 重新導向至建構子 C.b,但未定義 C.b

dart
class C {
  C.a() : this.b();
}

常見修正方式

#

如果必須呼叫遺失的建構子,則定義它

dart
class C {
  C.a() : this.b();
  C.b();
}

如果不需要呼叫遺失的建構子,則移除重新導向

dart
class C {
  C.a();
}

重新導向產生器至非產生器建構子

#

產生器建構子無法重新導向至工廠建構子。

描述

#

當產生器建構子重新導向至工廠建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為產生器建構子 C.a 重新導向至工廠建構子 C.b

dart
class C {
  C.a() : this.b();
  factory C.b() => C.a();
}

常見修正方式

#

如果產生器建構子不需要重新導向至另一個建構子,則移除重新導向。

dart
class C {
  C.a();
  factory C.b() => C.a();
}

如果產生器建構子必須重新導向至另一個建構子,則使另一個建構子成為產生器(非工廠)建構子

dart
class C {
  C.a() : this.b();
  C.b();
}

重新導向至抽象類別建構子

#

重新導向的建構子 '{0}' 無法重新導向至抽象類別 '{1}' 的建構子。

描述

#

當建構子重新導向至抽象類別中的建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 A 中的工廠建構子重新導向至 B 中的建構子,但 B 是抽象類別

dart
class A {
  factory A() = B;
}

abstract class B implements A {}

常見修正方式

#

如果程式碼重新導向至正確的建構子,則變更類別使其不是抽象類別

dart
class A {
  factory A() = B;
}

class B implements A {}

否則,變更工廠建構子,使其重新導向至具體類別中的建構子,或具有具體實作。

重新導向至無效函式類型

#

重新導向的建構子 '{0}' 與 '{1}' 的參數不相容。

描述

#

當工廠建構子嘗試重新導向至另一個建構子,但兩者具有不相容的參數時,分析器會產生此診斷訊息。如果重新導向的建構子的所有參數都可以傳遞給另一個建構子,且另一個建構子不需要任何未由重新導向的建構子宣告的參數,則參數是相容的。

範例

#

以下程式碼會產生此診斷訊息,因為 A 的建構子未宣告 B 的建構子需要的參數

dart
abstract class A {
  factory A() = B;
}

class B implements A {
  B(int x);
  B.zero();
}

以下程式碼會產生此診斷訊息,因為 A 的建構子宣告了一個具名參數 (y),但 B 的建構子不允許

dart
abstract class A {
  factory A(int x, {int y}) = B;
}

class B implements A {
  B(int x);
}

常見修正方式

#

如果有與重新導向的建構子相容的不同建構子,則重新導向至該建構子

dart
abstract class A {
  factory A() = B.zero;
}

class B implements A {
  B(int x);
  B.zero();
}

否則,更新重新導向的建構子以使其相容

dart
abstract class A {
  factory A(int x) = B;
}

class B implements A {
  B(int x);
}

重新導向至無效傳回類型

#

重新導向的建構子的回傳類型 '{0}' 不是 '{1}' 的子類型。

描述

#

當工廠建構子重新導向至一個建構子,但該建構子的回傳類型不是工廠建構子宣告產生的類型的子類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 A 不是 C 的子類別,這表示建構子 A() 回傳的值無法從建構子 C() 回傳

dart
class A {}

class B implements C {}

class C {
  factory C() = A;
}

常見修正方式

#

如果工廠建構子重新導向至錯誤類別中的建構子,則更新工廠建構子以重新導向至正確的建構子

dart
class A {}

class B implements C {}

class C {
  factory C() = B;
}

如果定義要重新導向的建構子的類別是應該回傳的類別,則使其成為工廠回傳類型的子類型

dart
class A implements C {}

class B implements C {}

class C {
  factory C() = A;
}

重新導向至遺失的建構子

#

在 '{1}' 中找不到建構子 '{0}'。

描述

#

當建構子重新導向至不存在的建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 A 中的工廠建構子重新導向至 B 中不存在的建構子

dart
class A {
  factory A() = B.name;
}

class B implements A {
  B();
}

常見修正方式

#

如果要重新導向的建構子是正確的,則定義該建構子

dart
class A {
  factory A() = B.name;
}

class B implements A {
  B();
  B.name();
}

如果應該調用不同的建構子,則更新重新導向

dart
class A {
  factory A() = B;
}

class B implements A {
  B();
}

重新導向至非類別

#

名稱 '{0}' 不是類型,不能在重新導向的建構子中使用。

描述

#

實作工廠建構子的一種方法是透過參考建構子的名稱來重新導向至另一個建構子。當重新導向至建構子以外的其他項目時,分析器會產生此診斷訊息。

範例

#

下列程式碼會產生此診斷,因為 f 是函式

dart
C f() => throw 0;

class C {
  factory C() = f;
}

常見修正方式

#

如果未定義建構子,則定義它或將其替換為已定義的建構子。

如果已定義建構子,但定義它的類別不可見,則您可能需要新增匯入。

如果您嘗試回傳函式回傳的值,則重寫建構子以從建構子的主體回傳值

dart
C f() => throw 0;

class C {
  factory C() => f();
}

重新導向至非_const_建構子

#

常數重新導向建構子無法重新導向至非常數建構子。

描述

#

當標記為 const 的建構子重新導向至未標記為 const 的建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為建構子 C.a 標記為 const,但重新導向至未標記為 const 的建構子 C.b

dart
class C {
  const C.a() : this.b();
  C.b();
}

常見修正方式

#

如果非常數建構子可以標記為 const,則將其標記為 const

dart
class C {
  const C.a() : this.b();
  const C.b();
}

如果非常數建構子無法標記為 const,則移除重新導向或從重新導向的建構子中移除 const

dart
class C {
  C.a() : this.b();
  C.b();
}

重新導向至類型別名展開為類型參數

#

重新導向的建構子無法重新導向至擴充為類型參數的類型別名。

描述

#

當重新導向的工廠建構子重新導向至類型別名,且類型別名擴充為類型別名的類型參數之一時,分析器會產生此診斷訊息。這是不允許的,因為類型參數的值是類型而不是類別。

範例

#

以下程式碼會產生此診斷訊息,因為重新導向至 B<A> 是指向一個類型別名,其值為 T,即使它看起來值應該是 A

dart
class A implements C {}

typedef B<T> = T;

abstract class C {
  factory C() = B<A>;
}

常見修正方式

#

使用類別名稱或定義為類別的類型別名,而不是定義為類型參數的類型別名

dart
class A implements C {}

abstract class C {
  factory C() = A;
}

在宣告之前參考

#

區域變數 '{0}' 在宣告之前無法被參考。

描述

#

當變數在宣告之前被參考時,分析器會產生此診斷訊息。在 Dart 中,變數在宣告它們的區塊中隨處可見,但只能在宣告後才能被參考。

分析器還會產生一個上下文訊息,指示宣告的位置。

範例

#

以下程式碼會產生此診斷訊息,因為 i 在宣告之前被使用

dart
void f() {
  print(i);
  int i = 5;
}

常見修正方式

#

如果您打算參考區域變數,則將宣告移至第一次參考之前

dart
void f() {
  int i = 5;
  print(i);
}

如果您打算參考來自外部範圍的名稱,例如參數、實例欄位或頂層變數,則重新命名區域宣告,使其不會隱藏外部變數。

dart
void f(int i) {
  print(i);
  int x = 5;
  print(x);
}

不可反駁情境中的可反駁模式

#

可否決模式無法在不可否決的上下文中使用。

描述

#

可否決模式在僅允許不可否決模式的上下文中使用時,分析器會產生此診斷訊息。

不允許的可否決模式是

  • 邏輯或
  • 關係
  • 空值檢查
  • 常數

檢查的上下文是

  • 基於模式的變數宣告
  • 基於模式的 for 迴圈
  • 左側帶有模式的賦值

範例

#

以下程式碼會產生此診斷訊息,因為空值檢查模式(一種可否決模式)在基於模式的變數宣告中,而基於模式的變數宣告不允許可否決模式

dart
void f(int? x) {
  var (_?) = x;
}

常見修正方式

#

重寫程式碼,使其不在不可否決的上下文中使用可否決模式。

關係模式運算元類型不可賦值

#

常數運算式類型 '{0}' 不可賦值給 '{2}' 運算子的參數類型 '{1}'。

描述

#

當關係模式的運算元的類型不可賦值給將要調用的運算子的參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為關係模式中的運算元 (0) 是 int,但 C 中定義的 > 運算子預期類型為 C 的物件

dart
class C {
  const C();

  bool operator >(C other) => true;
}

void f(C c) {
  switch (c) {
    case > 0:
      print('positive');
  }
}

常見修正方式

#

如果 switch 正在使用正確的值,則變更 case 以將值與正確類型的物件比較

dart
class C {
  const C();

  bool operator >(C other) => true;
}

void f(C c) {
  switch (c) {
    case > const C():
      print('positive');
  }
}

如果 switch 正在使用錯誤的值,則變更用於計算要比對的值的運算式

dart
class C {
  const C();

  bool operator >(C other) => true;

  int get toInt => 0;
}

void f(C c) {
  switch (c.toInt) {
    case > 0:
      print('positive');
  }
}

關係模式運算子傳回類型不可賦值給布林值

#

關係模式中使用的運算子的回傳類型必須可賦值給 'bool'。

描述

#

當關係模式參考到一個不產生 bool 類型值的運算子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為關係模式 > c2 中使用的運算子 > 回傳 int 類型的值,而不是 bool

dart
class C {
  const C();

  int operator >(C c) => 3;

  bool operator <(C c) => false;
}

const C c2 = C();

void f(C c1) {
  if (c1 case > c2) {}
}

常見修正方式

#

如果有應該使用的不同運算子,則變更運算子

dart
class C {
  const C();

  int operator >(C c) => 3;

  bool operator <(C c) => false;
}

const C c2 = C();

void f(C c1) {
  if (c1 case < c2) {}
}

如果運算子預期回傳 bool,則更新運算子的宣告

dart
class C {
  const C();

  bool operator >(C c) => true;

  bool operator <(C c) => false;
}

const C c2 = C();

void f(C c1) {
  if (c1 case > c2) {}
}

map_模式中的其餘元素

#

映射模式不能包含 rest 模式。

描述

#

當映射模式包含 rest 模式時,分析器會產生此診斷訊息。映射模式比對具有比模式中明確給出的鍵更多的鍵的映射(只要給定的鍵比對),因此 rest 模式是不必要的。

範例

#

以下程式碼會產生此診斷訊息,因為映射模式包含 rest 模式

dart
void f(Map<int, String> x) {
  if (x case {0: _, ...}) {}
}

常見修正方式

#

移除 rest 模式

dart
void f(Map<int, String> x) {
  if (x case {0: _}) {}
}

catch外部的_rethrow

#

rethrow 必須在 catch 子句內。

描述

#

rethrow 陳述式在 catch 子句外部時,分析器會產生此診斷訊息。rethrow 陳述式用於再次拋出捕獲的例外,但在 catch 子句外部沒有捕獲的例外。

範例

#

以下程式碼會產生此診斷訊息,因為 rethrow 陳述式在 catch 子句外部

dart
void f() {
  rethrow;
}

常見修正方式

#

如果您嘗試重新拋出例外,則將 rethrow 陳述式包裝在 catch 子句中

dart
void f() {
  try {
    // ...
  } catch (exception) {
    rethrow;
  }
}

如果您嘗試拋出新的例外,則將 rethrow 陳述式替換為 throw 運算式

dart
void f() {
  throw UnsupportedError('Not yet implemented');
}

產生器建構子中的傳回

#

建構子無法回傳值。

描述

#

當產生器建構子包含指定要回傳值的 return 陳述式時,分析器會產生此診斷訊息。產生器建構子總是回傳已建立的物件,因此無法回傳不同的物件。

範例

#

以下程式碼會產生此診斷訊息,因為 return 陳述式具有運算式

dart
class C {
  C() {
    return this;
  }
}

常見修正方式

#

如果建構子應建立新實例,則移除 return 陳述式或運算式

dart
class C {
  C();
}

如果建構子不應建立新實例,則將其轉換為工廠建構子

dart
class C {
  factory C() {
    return _instance;
  }

  static C _instance = C._();

  C._();
}

產生器中的傳回

#

無法從使用 'async*' 或 'sync*' 修飾符的產生器函式回傳值。

描述

#

當產生器函式(主體標記為 async*sync* 的函式)使用 return 陳述式回傳值,或由於使用 => 而隱式回傳值時,分析器會產生此診斷訊息。在任何這些情況下,它們都應該使用 yield 而不是 return

範例

#

以下程式碼會產生此診斷訊息,因為方法 f 是產生器,並且正在使用 return 回傳值

dart
Iterable<int> f() sync* {
  return 3;
}

以下程式碼會產生此診斷訊息,因為函式 f 是產生器,並且正在隱式回傳值

dart
Stream<int> f() async* => 3;

常見修正方式

#

如果函式正在使用 => 作為函式的主體,則將其轉換為區塊函式主體,並使用 yield 回傳值

dart
Stream<int> f() async* {
  yield 3;
}

如果方法旨在作為產生器,則使用 yield 回傳值

dart
Iterable<int> f() sync* {
  yield 3;
}

如果方法不旨在作為產生器,則從主體中移除修飾符(或者如果您要回傳 future,則使用 async

dart
int f() {
  return 3;
}

請勿儲存的傳回

#

'{0}' 使用 'doNotStore' 註解,不應回傳,除非 '{1}' 也使用註解。

描述

#

當使用 doNotStore 註解註解的值從一個沒有相同註解的方法、getter 或函式回傳時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為不應儲存調用 f 的結果,但函式 g 沒有註解來保留該語意

dart
import 'package:meta/meta.dart';

@doNotStore
int f() => 0;

int g() => f();

常見修正方式

#

如果應回傳的值是不應儲存的正確值,則使用 doNotStore 註解標記函式

dart
import 'package:meta/meta.dart';

@doNotStore
int f() => 0;

@doNotStore
int g() => f();

否則,從函式回傳不同的值

dart
import 'package:meta/meta.dart';

@doNotStore
int f() => 0;

int g() => 0;

無效類型的傳回

#

類型為 '{0}' 的值無法從建構子 '{2}' 回傳,因為它的回傳類型為 '{1}'。

類型為 '{0}' 的值無法從函式 '{2}' 回傳,因為它的回傳類型為 '{1}'。

類型為 '{0}' 的值無法從方法 '{2}' 回傳,因為它的回傳類型為 '{1}'。

描述

#

當方法或函式回傳的值的類型不可賦值給宣告的回傳類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 的回傳類型為 String,但正在回傳 int

dart
String f() => 3;

常見修正方式

#

如果回傳類型正確,則將要回傳的值替換為正確類型的值,可能透過轉換現有值

dart
String f() => 3.toString();

如果值正確,則變更回傳類型以符合

dart
int f() => 3;

來自封閉項的無效類型傳回

#

回傳的類型 '{0}' 無法從 '{1}' 函式回傳,這是閉包的上下文所要求的。

描述

#

當回傳運算式的靜態類型不可賦值給閉包所需的回傳類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 定義為回傳 String 的函式,但賦值給它的閉包回傳 int

dart
String Function(String) f = (s) => 3;

常見修正方式

#

如果回傳類型正確,則將回傳的值替換為正確類型的值,可能透過轉換現有值

dart
String Function(String) f = (s) => 3.toString();

沒有值的傳回

#

在 'return' 後面缺少回傳值。

描述

#

當分析器在宣告了回傳類型的函式中找到沒有運算式的 return 陳述式時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函式 f 預期回傳 int,但沒有回傳任何值

dart
int f() {
  return;
}

常見修正方式

#

新增一個計算要回傳的值的運算式

dart
int f() {
  return 0;
}

從核心匯出的_sdk_版本_async

#

類別 '{0}' 在 2.1 版之前未從 'dart:core' 匯出,但此程式碼必須能夠在更早版本上執行。

描述

#

當在 SDK 約束的下限小於 2.1.0 的程式碼中,在未匯入 dart:async 的程式庫中參考類別 FutureStream 時,分析器會產生此診斷訊息。在早期版本中,這些類別未在 dart:core 中定義,因此匯入是必要的。

範例

#

以下是一個 pubspec 的範例,它定義了一個 SDK 約束,其下限小於 2.1.0

yaml
environment:
  sdk: '>=2.0.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
void f(Future f) {}

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許參考類別

yaml
environment:
  sdk: '>=2.1.0 <2.4.0'

如果您需要支援舊版本的 SDK,則匯入 dart:async 程式庫。

dart
import 'dart:async';

void f(Future f) {}

const_情境中作為運算式的_sdk_版本

#

在常數運算式中使用 as 運算式在 2.3.2 版之前不受支援,但此程式碼必須能夠在更早版本上執行。

描述

#

當在 SDK 約束的下限小於 2.3.2 的程式碼中,在 常數上下文內找到 as 運算式時,分析器會產生此診斷訊息。在 常數上下文中使用 as 運算式在早期版本中不受支援,因此此程式碼將無法在早期版本的 SDK 上執行。

範例

#

以下是一個 pubspec 的範例,它定義了一個 SDK 約束,其下限小於 2.3.2

yaml
environment:
  sdk: '>=2.1.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
const num n = 3;
const int i = n as int;

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許使用運算式

yaml
environment:
  sdk: '>=2.3.2 <2.4.0'

如果您需要支援舊版本的 SDK,則重寫程式碼以不使用 as 運算式,或變更程式碼,使 as 運算式不在 常數上下文

dart
num x = 3;
int y = x as int;

const_情境中的_sdk_版本布林運算子

#

在常數上下文中,對 'bool' 運算元使用運算子 '{0}' 在 2.3.2 版之前不受支援,但此程式碼必須能夠在更早版本上執行。

描述

#

當在 SDK 約束的下限小於 2.3.2 的程式碼中,在 常數上下文內找到對類別 bool 使用 &|^ 運算子的任何情況時,分析器會產生此診斷訊息。在 常數上下文中使用這些運算子在早期版本中不受支援,因此此程式碼將無法在早期版本的 SDK 上執行。

範例

#

以下是一個 pubspec 的範例,它定義了一個 SDK 約束,其下限小於 2.3.2

yaml
environment:
  sdk: '>=2.1.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
const bool a = true;
const bool b = false;
const bool c = a & b;

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許使用運算子

yaml
environment:
 sdk: '>=2.3.2 <2.4.0'

如果您需要支援舊版本的 SDK,則重寫程式碼以不使用這些運算子,或變更程式碼,使運算式不在 常數上下文

dart
const bool a = true;
const bool b = false;
bool c = a & b;

sdk_版本建構子拆解

#

撕裂建構子需要 'constructor-tearoffs' 語言功能。

描述

#

當在 SDK 約束的下限小於 2.15 的程式碼中找到建構子撕裂時,分析器會產生此診斷訊息。建構子撕裂在早期版本中不受支援,因此此程式碼將無法在早期版本的 SDK 上執行。

範例

#

以下是一個 pubspec 的範例,它定義了一個 SDK 約束,其下限小於 2.15

yaml
environment:
  sdk: '>=2.9.0 <2.15.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
var setConstructor = Set.identity;

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許使用運算子

yaml
environment:
  sdk: '>=2.15.0 <2.16.0'

如果您需要支援舊版本的 SDK,則重寫程式碼以不使用建構子撕裂

dart
var setConstructor = () => Set.identity();

const_情境中的_sdk_版本_eq_eq運算子

#

對於非原始類型使用運算子 '==' 在 2.3.2 版之前不受支援,但此程式碼必須能夠在更早版本上執行。

描述

#

當在 SDK 約束的下限小於 2.3.2 的程式碼中,在 常數上下文內找到對非原始類型使用運算子 == 時,分析器會產生此診斷訊息。在 常數上下文中使用此運算子在早期版本中不受支援,因此此程式碼將無法在早期版本的 SDK 上執行。

範例

#

以下是一個 pubspec 的範例,它定義了一個 SDK 約束,其下限小於 2.3.2

yaml
environment:
  sdk: '>=2.1.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
class C {}
const C a = null;
const C b = null;
const bool same = a == b;

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許使用運算子

yaml
environment:
  sdk: '>=2.3.2 <2.4.0'

如果您需要支援舊版本的 SDK,則重寫程式碼以不使用 == 運算子,或變更程式碼,使運算式不在 常數上下文

dart
class C {}
const C a = null;
const C b = null;
bool same = a == b;

sdk_版本擴充功能方法

#

擴充方法直到 2.6.0 版本才開始支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.6.0 的程式碼中,發現擴充宣告或擴充覆寫時,分析器會產生此診斷訊息。由於更早的版本不支援擴充方法,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下範例 pubspec 定義了 SDK 約束條件,其下限低於 2.6.0

yaml
environment:
 sdk: '>=2.4.0 <2.7.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
extension E on String {
  void sayHello() {
    print('Hello $this');
  }
}

常見修正方式

#

如果您不需要支援舊版 SDK,則可以提高 SDK 約束條件,以允許使用此語法

yaml
environment:
  sdk: '>=2.6.0 <2.7.0'

如果您需要支援舊版 SDK,則請重寫程式碼,使其不使用擴充方法。最常見的做法是將擴充方法的成員重寫為頂層函式(或方法),並將原本會繫結到 this 的值作為參數傳遞。

dart
void sayHello(String s) {
  print('Hello $s');
}

sdk_版本_gt_gt_gt運算子

#

運算子 '>>>' 直到 2.14.0 版本才開始支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.14.0 的程式碼中,使用運算子 >>> 時,分析器會產生此診斷訊息。由於更早的版本不支援此運算子,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下範例 pubspec 定義了 SDK 約束條件,其下限低於 2.14.0

yaml
environment:
 sdk: '>=2.0.0 <2.15.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
int x = 3 >>> 4;

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許使用運算子

yaml
environment:
  sdk: '>=2.14.0 <2.15.0'

如果您需要支援舊版 SDK,則請重寫程式碼,使其不使用 >>> 運算子

dart
int x = logicalShiftRight(3, 4);

int logicalShiftRight(int leftOperand, int rightOperand) {
  int divisor = 1 << rightOperand;
  if (divisor == 0) {
    return 0;
  }
  return leftOperand ~/ divisor;
}

const_情境中的_sdk_版本_is運算式

#

在常數環境中使用 is 運算式直到 2.3.2 版本才開始支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.3.2 的程式碼中,發現 常數環境 內的 is 運算式時,分析器會產生此診斷訊息。由於更早的版本不支援在 常數環境 中使用 is 運算式,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下是一個 pubspec 的範例,它定義了一個 SDK 約束,其下限小於 2.3.2

yaml
environment:
  sdk: '>=2.1.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
const Object x = 4;
const y = x is int ? 0 : 1;

常見修正方式

#

如果您不需要支援舊版本的 SDK,則可以提高 SDK 約束以允許使用運算式

yaml
environment:
  sdk: '>=2.3.2 <2.4.0'

如果您需要支援舊版 SDK,則可以重寫程式碼,使其不使用 is 運算子;或者,如果不可行,則變更程式碼,使 is 運算式不在 常數環境 中。

dart
const Object x = 4;
var y = x is int ? 0 : 1;

sdk_版本_never

#

類型 'Never' 直到 2.12.0 版本才開始支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.12.0 的程式碼中,發現對類別 Never 的參考時,分析器會產生此診斷訊息。由於更早的版本未定義此類別,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下範例 pubspec 定義了 SDK 約束條件,其下限低於 2.12.0

yaml
environment:
  sdk: '>=2.5.0 <2.6.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
Never n;

常見修正方式

#

如果您不需要支援舊版 SDK,則可以提高 SDK 約束條件,以允許使用此類型

yaml
environment:
  sdk: '>=2.12.0 <2.13.0'

如果您需要支援舊版 SDK,則請重寫程式碼,使其不參考此類別

dart
dynamic x;

sdk_版本_set_字面值

#

Set 字面值直到 2.2 版本才開始支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.2.0 的程式碼中,發現 set 字面值時,分析器會產生此診斷訊息。由於更早的版本不支援 set 字面值,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下範例 pubspec 定義了 SDK 約束條件,其下限低於 2.2.0

yaml
environment:
  sdk: '>=2.1.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
var s = <int>{};

常見修正方式

#

如果您不需要支援舊版 SDK,則可以提高 SDK 約束條件,以允許使用此語法

yaml
environment:
  sdk: '>=2.2.0 <2.4.0'

如果您確實需要支援舊版 SDK,則請將 set 字面值替換為不使用字面值來建立 set 的程式碼

dart
var s = new Set<int>();

sdk_版本_UI作為程式碼

#

for、if 和 spread 元素直到 2.3.0 版本才開始支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.3.0 的程式碼中,發現 for、if 或 spread 元素時,分析器會產生此診斷訊息。由於更早的版本不支援使用 for、if 或 spread 元素,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下範例 pubspec 定義了 SDK 約束條件,其下限低於 2.3.0

yaml
environment:
  sdk: '>=2.2.0 <2.4.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
var digits = [for (int i = 0; i < 10; i++) i];

常見修正方式

#

如果您不需要支援舊版 SDK,則可以提高 SDK 約束條件,以允許使用此語法

yaml
environment:
  sdk: '>=2.3.0 <2.4.0'

如果您需要支援舊版 SDK,則請重寫程式碼,使其不使用這些元素

dart
var digits = _initializeDigits();

List<int> _initializeDigits() {
  var digits = <int>[];
  for (int i = 0; i < 10; i++) {
    digits.add(i);
  }
  return digits;
}

const_情境中的_sdk_版本_UI作為程式碼

#

if 和 spread 元素直到 2.5.0 版本才開始在常數運算式中支援,但這段程式碼需要在更早的版本上也能執行。

描述

#

當在 SDK 約束條件的下限低於 2.5.0 的程式碼中,發現 常數環境 內的 if 或 spread 元素時,分析器會產生此診斷訊息。由於更早的版本不支援在 常數環境 中使用 if 或 spread 元素,因此這段程式碼將無法在更早版本的 SDK 上執行。

範例

#

以下範例 pubspec 定義了 SDK 約束條件,其下限低於 2.5.0

yaml
environment:
  sdk: '>=2.4.0 <2.6.0'

在具有該 pubspec 的套件中,如下程式碼會產生此診斷訊息

dart
const a = [1, 2];
const b = [...a];

常見修正方式

#

如果您不需要支援舊版 SDK,則可以提高 SDK 約束條件,以允許使用此語法

yaml
environment:
  sdk: '>=2.5.0 <2.6.0'

如果您需要支援舊版 SDK,則請重寫程式碼,使其不使用這些元素

dart
const a = [1, 2];
const b = [1, 2];

如果不可行,則變更程式碼,使該元素不在 常數環境 中。

dart
const a = [1, 2];
var b = [...a];

set_元素類型不可賦值

#

元素類型 '{0}' 無法指派給 set 類型 '{1}'。

描述

#

當 set 字面值中的元素類型無法指派給 set 的元素類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為字串字面值 '0' 的類型為 String,無法指派給 int,也就是 set 的元素類型。

dart
var s = <int>{'0'};

常見修正方式

#

如果 set 字面值的元素類型錯誤,則請變更 set 的元素類型

dart
var s = <String>{'0'};

如果元素的類型錯誤,則請變更元素

dart
var s = <int>{'0'.length};

共用的延遲載入前置詞

#

延遲匯入的前綴詞不能用於其他匯入指示詞。

描述

#

當延遲匯入中的前綴詞也用於其他匯入(無論是否延遲)作為前綴詞時,分析器會產生此診斷訊息。延遲匯入中的前綴詞不能與其他匯入共用,因為前綴詞用於載入匯入的程式庫。

範例

#

以下程式碼會產生此診斷訊息,因為前綴詞 x 用於延遲匯入的前綴詞,也用於另一個匯入。

dart
import 'dart:math' deferred as x;
import 'dart:convert' as x;

var y = x.json.encode(x.min(0, 1));

常見修正方式

#

如果您可以使用不同的名稱作為延遲匯入,請這樣做

dart
import 'dart:math' deferred as math;
import 'dart:convert' as x;

var y = x.json.encode(math.min(0, 1));

如果您可以使用不同的名稱作為其他匯入,請這樣做

dart
import 'dart:math' deferred as x;
import 'dart:convert' as convert;

var y = convert.json.encode(x.min(0, 1));

大小註解維度

#

'Array' 必須具有符合維度的 'Array' 註解。

描述

#

Array 註解中指定的維度數量與欄位類型指定的巢狀陣列數量不符時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 a0 的類型具有三個巢狀陣列,但在 Array 註解中僅給定兩個維度。

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8, 8)
  external Array<Array<Array<Uint8>>> a0;
}

常見修正方式

#

如果欄位的類型正確,則請修正註解以使其具有所需的維度數量

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8, 8, 4)
  external Array<Array<Array<Uint8>>> a0;
}

如果欄位的類型錯誤,則請修正欄位的類型

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(8, 8)
  external Array<Array<Uint8>> a0;
}

靜態存取實例成員

#

無法使用靜態存取來存取實例成員 '{0}'。

描述

#

當使用類別名稱來存取實例欄位時,分析器會產生此診斷訊息。實例欄位不存在於類別上;它們僅存在於類別的實例上。

範例

#

以下程式碼會產生此診斷訊息,因為 x 是一個實例欄位。

dart
class C {
  static int a = 0;

  int b = 0;
}

int f() => C.b;

常見修正方式

#

如果您打算存取靜態欄位,則請將欄位名稱變更為現有的靜態欄位

dart
class C {
  static int a = 0;

  int b = 0;
}

int f() => C.a;

如果您打算存取實例欄位,則請使用類別的實例來存取欄位

dart
class C {
  static int a = 0;

  int b = 0;
}

int f(C c) => c.b;

base或_final的子類型不是_base、final或_sealed

#

mixin '{0}' 必須為 'base',因為超類型 '{1}' 為 'base'。

mixin '{0}' 必須為 'base',因為超類型 '{1}' 為 'final'。

類型 '{0}' 必須為 'base'、'final' 或 'sealed',因為超類型 '{1}' 為 'base'。

類型 '{0}' 必須為 'base'、'final' 或 'sealed',因為超類型 '{1}' 為 'final'。

描述

#

當類別或 mixin 具有直接或間接的超類型為 basefinal,但該類別或 mixin 本身未標記為 basefinalsealed 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 BA 的子類型,而 Abase 類別,但 B 既不是 basefinal 也不是 sealed

dart
base class A {}
class B extends A {}

常見修正方式

#

basefinalsealed 新增至類別或 mixin 宣告中

dart
base class A {}
final class B extends A {}

延遲載入類別的子類型

#

類別和 mixin 無法實作延遲類別。

類別無法擴展延遲類別。

類別無法混入延遲類別。

描述

#

當類型(類別或 mixin)是使用延遲匯入匯入的程式庫中的類別的子類型時,分析器會產生此診斷訊息。類型的超類型必須與類型同時編譯,而延遲程式庫中的類別要等到程式庫載入後才會編譯。

有關更多資訊,請查看 延遲載入程式庫

範例

#

假設檔案 a.dart 定義了類別 A

dart
class A {}

以下程式碼會產生此診斷訊息,因為 B 的超類別是在延遲程式庫中宣告的。

dart
import 'a.dart' deferred as a;

class B extends a.A {}

常見修正方式

#

如果您需要建立延遲程式庫中類型的子類型,則請移除 deferred 關鍵字

dart
import 'a.dart' as a;

class B extends a.A {}

不允許類型的子類型

#

'{0}' 無法用作超類別約束。

類別和 mixin 無法實作 '{0}'。

類別無法擴展 '{0}'。

類別無法混入 '{0}'。

描述

#

當限制類別之一用於 extendsimplementswithon 子句中時,分析器會產生此診斷訊息。類別 booldoubleFutureOrintNullnumString 都以此方式受到限制,以實現更有效率的實作。

範例

#

以下程式碼會產生此診斷訊息,因為 String 用於 extends 子句中。

dart
class A extends String {}

以下程式碼會產生此診斷訊息,因為 String 用於 implements 子句中。

dart
class B implements String {}

以下程式碼會產生此診斷訊息,因為 String 用於 with 子句中。

dart
class C with String {}

以下程式碼會產生此診斷訊息,因為 String 用於 on 子句中。

dart
mixin M on String {}

常見修正方式

#

如果應指定不同的類型,則請替換該類型

dart
class A extends Object {}

如果沒有其他合適的類型,則移除該類型,並可能移除整個子句

dart
class B {}

ffi_類別的子類型

#

類別 '{0}' 無法擴展 '{1}'。

類別 '{0}' 無法實作 '{1}'。

類別 '{0}' 無法混入 '{1}'。

描述

#

當類別擴展任何 FFI 類別(StructUnion 除外),或實作或混入任何 FFI 類別時,分析器會產生此診斷訊息。StructUnion 是唯一可以作為子類型的 FFI 類別,並且只能透過擴展它們來作為子類型。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 擴展了 Double

dart
import 'dart:ffi';

final class C extends Double {}

常見修正方式

#

如果類別應擴展 StructUnion,則請變更類別的宣告

dart
import 'dart:ffi';

final class C extends Struct {
  @Int32()
  external int i;
}

如果類別不應擴展 StructUnion,則請移除對 FFI 類別的任何參考

dart
final class C {}

sealed_類別的子類型

#

類別 '{0}' 不應被擴展、混入或實作,因為它是 sealed 類別。

描述

#

當 sealed 類別(具有 sealed 註解或繼承或混入 sealed 類別的類別)在類別或 mixin 宣告的 extendsimplementswith 子句中被參考,且該宣告與 sealed 類別不在同一個套件中時,分析器會產生此診斷訊息。

範例

#

假設一個套件中的程式庫(非正在分析的套件)包含以下內容:

dart
import 'package:meta/meta.dart';

class A {}

@sealed
class B {}

以下程式碼會產生此診斷訊息,因為 C(與 B 不在同一個套件中)正在擴展 sealed 類別 B

dart
import 'package:a/a.dart';

class C extends B {}

常見修正方式

#

如果類別不需要成為 sealed 類別的子類型,則請變更宣告,使其不是子類型

dart
import 'package:a/a.dart';

class B extends A {}

如果類別需要成為 sealed 類別的子類型,則請變更 sealed 類別,使其不再是 sealed 類別,或將子類別移至與 sealed 類別相同的套件中。

struct_類別的子類型

#

類別 '{0}' 無法擴展 '{1}',因為 '{1}' 是 'Struct'、'Union' 或 'AbiSpecificInteger' 的子類型。

類別 '{0}' 無法實作 '{1}',因為 '{1}' 是 'Struct'、'Union' 或 'AbiSpecificInteger' 的子類型。

類別 '{0}' 無法混入 '{1}',因為 '{1}' 是 'Struct'、'Union' 或 'AbiSpecificInteger' 的子類型。

描述

#

當類別擴展、實作或混入擴展 StructUnion 的類別時,分析器會產生此診斷訊息。類別只能直接擴展 StructUnion

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 擴展了 S,而 S 擴展了 Struct

dart
import 'dart:ffi';

final class S extends Struct {
  external Pointer f;
}

final class C extends S {
  external Pointer g;
}

常見修正方式

#

如果您嘗試定義一個 struct 或 union,其與不同的 struct 或 union 共用某些宣告的欄位,則請直接擴展 StructUnion 並複製共用欄位

dart
import 'dart:ffi';

final class S extends Struct {
  external Pointer f;
}

final class C extends Struct {
  external Pointer f;

  external Pointer g;
}

超類型展開為類型參數

#

擴展為類型參數的類型別名無法被實作。

擴展為類型參數的類型別名無法被混入。

擴展為類型參數的類型別名無法用作超類別約束。

擴展為類型參數的類型別名無法用作超類別。

描述

#

當擴展為類型參數的類型別名用於 extendsimplementswithon 子句中時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴展為類型參數 S 的類型別名 T 用於類別 Cextends 子句中。

dart
typedef T<S> = S;

class C extends T<Object> {}

常見修正方式

#

直接使用類型引數的值

dart
typedef T<S> = S;

class C extends Object {}

super_形式參數類型不是關聯項的子類型

#

此參數的類型 '{0}' 不是相關聯的超建構子參數的類型 '{1}' 的子類型。

描述

#

當超參數的類型不是超建構子中對應參數的子類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 B 的建構子中超參數 x 的類型不是類別 A 的建構子中參數 x 的子類型。

dart
class A {
  A(num x);
}

class B extends A {
  B(String super.x);
}

常見修正方式

#

如果超參數的類型可以與超建構子的參數相同,則請從超參數中移除類型註解(如果類型是隱含的,則會從超建構子中的類型推斷出來)

dart
class A {
  A(num x);
}

class B extends A {
  B(super.x);
}

如果超參數的類型可以是相應參數類型之子類型,則請變更超參數的類型

dart
class A {
  A(num x);
}

class B extends A {
  B(int super.x);
}

如果超參數的類型無法變更,則請使用一般參數而不是超參數

dart
class A {
  A(num x);
}

class B extends A {
  B(String x) : super(x.length);
}

沒有關聯具名的_super_形式參數

#

沒有相關聯的具名超建構子參數。

描述

#

當建構子中存在具名超參數,而隱含或明確調用的超建構子沒有同名的具名參數時,分析器會產生此診斷訊息。

具名超參數會依名稱與超建構子中的具名參數相關聯。

範例

#

以下程式碼會產生此診斷訊息,因為 A 中的建構子沒有名為 y 的參數。

dart
class A {
  A({int? x});
}

class B extends A {
  B({super.y});
}

常見修正方式

#

如果超參數應與超建構子中現有的參數相關聯,則請變更名稱以符合對應參數的名稱

dart
class A {
  A({int? x});
}

class B extends A {
  B({super.x});
}

如果超參數應與尚未新增至超建構子的參數相關聯,則請新增該參數

dart
class A {
  A({int? x, int? y});
}

class B extends A {
  B({super.y});
}

如果超參數不對應於超建構子的具名參數,則請將其變更為一般參數

dart
class A {
  A({int? x});
}

class B extends A {
  B({int? y});
}

沒有關聯位置的_super_形式參數

#

沒有相關聯的位置超建構子參數。

描述

#

當建構子中存在位置超參數,而隱含或明確調用的超建構子在對應索引處沒有位置參數時,分析器會產生此診斷訊息。

位置超參數會依索引與超建構子中的位置參數相關聯。也就是說,第一個超參數與超建構子中的第一個位置參數相關聯,第二個與第二個相關聯,依此類推。

範例

#

以下程式碼會產生此診斷訊息,因為 B 中的建構子具有位置超參數,但 A 中的超建構子中沒有位置參數。

dart
class A {
  A({int? x});
}

class B extends A {
  B(super.x);
}

以下程式碼會產生此診斷訊息,因為 B 中的建構子具有兩個位置超參數,但 A 中的超建構子中只有一個位置參數,這表示 y 沒有對應的參數。

dart
class A {
  A(int x);
}

class B extends A {
  B(super.x, super.y);
}

常見修正方式

#

如果超建構子應具有對應於超參數的位置參數,則請適當地更新超建構子

dart
class A {
  A(int x, int y);
}

class B extends A {
  B(super.x, super.y);
}

如果超建構子正確或無法變更,則請將超參數轉換為一般參數

dart
class A {
  A(int x);
}

class B extends A {
  B(super.x, int y);
}

super_調用不是最後一個

#

(先前稱為 invalid_super_invocation

超建構子呼叫必須是初始化列表中的最後一個項目:'{0}'。

描述

#

當建構子的初始化列表包含對超類別中建構子的調用,但該調用不是初始化列表中的最後一個項目時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為對超類別建構子的調用不是初始化列表中的最後一個項目。

dart
class A {
  A(int x);
}

class B extends A {
  B(int x) : super(x), assert(x >= 0);
}

常見修正方式

#

將對超類別建構子的調用移至初始化列表的末尾

dart
class A {
  A(int x);
}

class B extends A {
  B(int x) : assert(x >= 0), super(x);
}

列舉建構子中的_super

#

列舉建構子不能有 'super' 初始化子。

描述

#

當列舉中的建構子的初始化列表包含對超建構子的調用時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列舉 E 中的建構子在初始化列表中具有超建構子調用。

dart
enum E {
  e;

  const E() : super();
}

常見修正方式

#

移除超建構子調用

dart
enum E {
  e;

  const E();
}

擴充功能中的_super

#

'super' 關鍵字不能在擴充方法中使用,因為擴充方法沒有超類別。

描述

#

當在擴充方法內宣告的成員使用 super 關鍵字時,分析器會產生此診斷訊息。擴充方法不是類別,也沒有超類別,因此 super 關鍵字沒有任何用途。

範例

#

以下程式碼會產生此診斷訊息,因為 super 不能在擴充方法中使用。

dart
extension E on Object {
  String get displayString => super.toString();
}

常見修正方式

#

移除 super 關鍵字

dart
extension E on Object {
  String get displayString => toString();
}

擴充功能類型中的_super

#

'super' 關鍵字不能在擴充類型中使用,因為擴充類型沒有超類別。

描述

#

super 用於擴充類型的實例成員中時,分析器會產生此診斷訊息。擴充類型沒有超類別,因此沒有可以調用的繼承成員。

範例

#

以下程式碼會產生此診斷訊息,因為

dart
extension type E(String s) {
  void m() {
    super.m();
  }
}

常見修正方式

#

替換或移除 super 調用

dart
extension type E(String s) {
  void m() {
    s.toLowerCase();
  }
}

無效情境中的_super

#

'super' 調用的上下文無效。

描述

#

當關鍵字 super 在實例方法之外使用時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 super 用於頂層函式中。

dart
void f() {
  super.f();
}

常見修正方式

#

重寫程式碼,使其不使用 super

重新導向建構子中的_super

#

重新導向的建構子不能有 'super' 初始化子。

描述

#

當重新導向到另一個建構子的建構子也嘗試調用超類別的建構子時,分析器會產生此診斷訊息。當調用重新導向建構子所重新導向的建構子時,將會調用超類別建構子。

範例

#

以下程式碼會產生此診斷訊息,因為建構子 C.a 同時重新導向到 C.b 並調用超類別的建構子。

dart
class C {
  C.a() : this.b(), super();
  C.b();
}

常見修正方式

#

移除 super 建構子的調用

dart
class C {
  C.a() : this.b();
  C.b();
}

switch_case正常完成

#

'case' 不應正常完成。

描述

#

switch 語句中 case 標籤後的語句可能 fall through 到下一個 casedefault 標籤時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為值為零 (0) 的 case 標籤 fall through 到 default 語句。

dart
void f(int a) {
  switch (a) {
    case 0:
      print(0);
    default:
      return;
  }
}

常見修正方式

#

變更控制流程,使 case 不會 fall through。有多種方法可以做到這一點,包括在目前語句列表的末尾新增以下其中一項:

  • return 語句、
  • throw 運算式、
  • break 語句、
  • continue
  • 傳回類型為 Never 的函式或方法的調用。

switch_運算式不可賦值

#

switch 運算式的類型 '{0}' 無法指派給 case 運算式的類型 '{1}'。

描述

#

switch 語句中運算式的類型無法指派給 case 子句中運算式的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 s 的類型 (String) 無法指派給 0 的類型 (int)。

dart
void f(String s) {
  switch (s) {
    case 0:
      break;
  }
}

常見修正方式

#

如果 case 運算式的類型正確,則請變更 switch 語句中的運算式以使其具有正確的類型

dart
void f(String s) {
  switch (int.parse(s)) {
    case 0:
      break;
  }
}

如果 switch 運算式的類型正確,則請變更 case 運算式以使其具有正確的類型

dart
void f(String s) {
  switch (s) {
    case '0':
      break;
  }
}

抽象類別的產生器建構子的拆解

#

抽象類別的產生器建構子無法被 tear off。

描述

#

當從抽象類別 tear off 產生器建構子時,分析器會產生此診斷訊息。這是不允許的,因為建立抽象類別的實例是無效的,這表示 tear off 的建構子沒有任何有效的用途。

範例

#

以下程式碼會產生此診斷訊息,因為正在 tear off 建構子 C.new,而類別 C 是一個抽象類別。

dart
abstract class C {
  C();
}

void f() {
  C.new;
}

常見修正方式

#

Tear off 具體類別的建構子。

註解中的文字方向碼點

#

Unicode 代碼點 'U+{0}' 會變更文字的外觀,使其與編譯器解讀的方式不同。

描述

#

當分析器遇到包含文字方向 Unicode 代碼點的原始碼時,會產生此診斷訊息。這些代碼點會導致字串字面值或註解中的原始碼以不同於編輯器中顯示的方式進行解讀和編譯,從而導致可能的安全性漏洞。

範例

#

以下程式碼會產生兩次此診斷訊息,因為標籤字串的開頭和結尾都有隱藏字元。

dart
var label = 'Interactive text';

常見修正方式

#

如果代碼點旨在包含在字串字面值中,則請逸出它們

dart
var label = '\u202AInteractive text\u202C';

如果代碼點不旨在包含在字串字面值中,則請移除它們

dart
var label = 'Interactive text';

字面值中的文字方向碼點

#

Unicode 代碼點 'U+{0}' 會變更文字的外觀,使其與編譯器解讀的方式不同。

描述

#

當分析器遇到包含文字方向 Unicode 代碼點的原始碼時,會產生此診斷訊息。這些代碼點會導致字串字面值或註解中的原始碼以不同於編輯器中顯示的方式進行解讀和編譯,從而導致可能的安全性漏洞。

範例

#

以下程式碼會產生兩次此診斷訊息,因為標籤字串的開頭和結尾都有隱藏字元。

dart
var label = 'Interactive text';

常見修正方式

#

如果代碼點旨在包含在字串字面值中,則請逸出它們

dart
var label = '\u202AInteractive text\u202C';

如果代碼點不旨在包含在字串字面值中,則請移除它們

dart
var label = 'Interactive text';

無效類型的拋出

#

拋出運算式的類型 '{0}' 必須可指派給 'Object'。

描述

#

當 throw 運算式中運算式的類型無法指派給 Object 時,分析器會產生此診斷訊息。拋出 null 是無效的,因此使用可能評估為 null 的運算式也是無效的。

範例

#

以下程式碼會產生此診斷訊息,因為 s 可能為 null

dart
void f(String? s) {
  throw s;
}

常見修正方式

#

為運算式新增明確的 null 檢查

dart
void f(String? s) {
  throw s!;
}

最上層循環

#

無法推斷 '{0}' 的類型,因為它透過循環 {1} 依賴於自身。

描述

#

當頂層變數沒有類型註解,且變數的初始化器直接或間接地參考該變數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為變數 xy 是根據彼此定義的,並且兩者都沒有明確的類型,因此無法推斷另一個的類型。

dart
var x = y;
var y = x;

常見修正方式

#

如果這兩個變數不需要互相參考,則請打破循環

dart
var x = 0;
var y = x;

如果這兩個變數需要互相參考,則請至少為其中一個變數提供明確的類型

dart
int x = y;
var y = x;

請注意,但是,雖然此程式碼不會產生任何診斷訊息,但除非至少其中一個變數在參考循環中的任何變數之前被指派一個不依賴於其他變數的值,否則它將在運行時產生堆疊溢位。

類型別名無法參考自身

#

類型定義不能直接或透過另一個類型定義遞迴地參考自身。

描述

#

當類型定義直接或間接地參考自身時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 F 透過 G 間接地依賴於自身。

dart
typedef F = void Function(G);
typedef G = void Function(F);

常見修正方式

#

變更循環中的一個或多個類型定義,使它們都不參考自身

dart
typedef F = void Function(G);
typedef G = void Function(int);

類型註解延遲載入類別

#

延遲類型 '{0}' 不能用於宣告、轉型或類型測試中。

描述

#

當類型註解在變數宣告中,或在轉型 (as) 或類型測試 (is) 中使用的類型是從使用延遲匯入匯入的程式庫中宣告的類型時,分析器會產生此診斷訊息。這些類型需要在編譯時可用,但實際上並非如此。

有關更多資訊,請查看 延遲載入程式庫

範例

#

以下程式碼會產生此診斷訊息,因為參數 f 的類型是從延遲程式庫匯入的。

dart
import 'dart:io' deferred as io;

void f(io.File f) {}

常見修正方式

#

如果您需要參考匯入的類型,則請移除 deferred 關鍵字

dart
import 'dart:io' as io;

void f(io.File f) {}

如果需要延遲匯入,並且有另一個合適的類型,則請使用該類型來代替延遲程式庫中的類型。

類型引數不符合界限

#

'{0}' 不符合類型參數 '{1}' 的界限 '{2}'。

描述

#

當類型引數與對應類型參數的界限不同或不是其子類別時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 String 不是 num 的子類別。

dart
class A<E extends num> {}

var a = A<String>();

常見修正方式

#

將類型引數變更為界限的子類別

dart
class A<E extends num> {}

var a = A<int>();

使用_null的類型檢查

#

非 null 的測試應使用 '!= null' 完成。

Null 的測試應使用 '== null' 完成。

描述

#

當存在類型檢查(使用 as 運算子)且類型為 Null 時,分析器會產生此診斷訊息。只有一個值的類型為 Null,因此當明確測試 null 時,程式碼既更具可讀性,效能也更高。

範例

#

以下程式碼會產生此診斷訊息,因為程式碼正在使用類型檢查來測試 s 的值是否為 null

dart
void f(String? s) {
  if (s is Null) {
    return;
  }
  print(s);
}

以下程式碼會產生此診斷訊息,因為程式碼正在使用類型檢查來測試 s 的值是否為 null 以外的內容。

dart
void f(String? s) {
  if (s is! Null) {
    print(s);
  }
}

常見修正方式

#

將類型檢查替換為與 null 的等效比較

dart
void f(String? s) {
  if (s == null) {
    return;
  }
  print(s);
}

靜態參考的類型參數

#

靜態成員不能參考類別的類型參數。

描述

#

當靜態成員參考為類別宣告的類型參數時,分析器會產生此診斷訊息。類型參數僅對類別的實例才有意義。

範例

#

以下程式碼會產生此診斷訊息,因為靜態方法 hasType 參考了類型參數 T

dart
class C<T> {
  static bool hasType(Object o) => o is T;
}

常見修正方式

#

如果成員可以是實例成員,則請移除關鍵字 static

dart
class C<T> {
  bool hasType(Object o) => o is T;
}

如果成員必須是靜態成員,則請使該成員成為泛型

dart
class C<T> {
  static bool hasType<S>(Object o) => o is S;
}

請注意,但是,TS 之間沒有關係,因此第二個選項會將語義變更為可能預期的語義。

其界限的超類型的類型參數

#

'{0}' 不能是其上限的超類型。

描述

#

當類型參數的界限(extends 關鍵字後面的類型)直接或間接地是類型參數本身時,分析器會產生此診斷訊息。聲明類型參數必須與自身相同,或是自身的子類型,或是自身的子類型是沒有幫助的,因為它始終會與自身相同。

範例

#

以下程式碼會產生此診斷訊息,因為 T 的界限為 T

dart
class C<T extends T> {}

以下程式碼會產生此診斷訊息,因為 T1 的界限為 T2,而 T2 的界限為 T1,實際上使 T1 的界限變為 T1

dart
class C<T1 extends T2, T2 extends T1> {}

常見修正方式

#

如果類型參數需要成為某種類型的子類別,則請將界限替換為所需的類型

dart
class C<T extends num> {}

如果類型參數可以是任何類型,則請移除 extends 子句

dart
class C<T> {}

使用非類型的類型測試

#

名稱 '{0}' 不是類型,不能在 'is' 運算式中使用。

描述

#

isis! 測試的右側不是類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為右側是參數,而不是類型。

dart
typedef B = int Function(int);

void f(Object a, B b) {
  if (a is b) {
    return;
  }
}

常見修正方式

#

如果您打算使用類型測試,則請將右側替換為類型

dart
typedef B = int Function(int);

void f(Object a, B b) {
  if (a is B) {
    return;
  }
}

如果您打算使用不同類型的測試,則請變更測試

dart
typedef B = int Function(int);

void f(Object a, B b) {
  if (a == b) {
    return;
  }
}

使用未定義名稱的類型測試

#

名稱 '{0}' 未定義,因此無法在 'is' 運算式中使用。

描述

#

當類型測試運算式中 is 後面的名稱未定義時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 Srting 未定義。

dart
void f(Object o) {
  if (o is Srting) {
    // ...
  }
}

常見修正方式

#

將名稱替換為型別的名稱。

dart
void f(Object o) {
  if (o is String) {
    // ...
  }
}

未檢查地使用可為 Null 值

#

可為 null 的運算式不能用作條件。

可為 null 的運算式不能在 for-in 迴圈中用作迭代器。

可為 null 的運算式不能用於 spread 中。

可為 null 的運算式不能用於 yield-each 語句中。

函式不能無條件調用,因為它可能為 'null'。

方法 '{0}' 不能無條件調用,因為接收器可能為 'null'。

運算子 '{0}' 不能無條件調用,因為接收器可能為 'null'。

屬性 '{0}' 不能無條件存取,因為接收器可能為 'null'。

描述

#

可能為非 null 的類型的運算式在未先驗證值是否為 null 的情況下被取值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 s 在被參考的點上可能為 null

dart
void f(String? s) {
  if (s.length > 3) {
    // ...
  }
}

常見修正方式

#

如果值確實可能為 null,則請新增測試以確保僅在值不為 null 時才存取成員

dart
void f(String? s) {
  if (s != null && s.length > 3) {
    // ...
  }
}

如果運算式是變數,且值永遠不應為 null,則請將變數的類型變更為不可為 null

dart
void f(String s) {
  if (s.length > 3) {
    // ...
  }
}

如果您認為運算式的值永遠不應為 null,但您無法變更變數的類型,並且您願意承擔在您錯誤時在運行時拋出異常的風險,則可以斷言該值不為 null

dart
void f(String? s) {
  if (s!.length > 3) {
    // ...
  }
}

未定義的註解

#

未定義的名稱「{0}」被用作註解。

描述

#

當未定義的名稱被用作註解時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 undefined 未被定義

dart
@undefined
void f() {}

常見修正方式

#

如果名稱正確,但尚未宣告,則將該名稱宣告為常數值

dart
const undefined = 'undefined';

@undefined
void f() {}

如果名稱錯誤,請將該名稱替換為有效的常數名稱

dart
@deprecated
void f() {}

否則,請移除該註解。

未定義的類別

#

未定義的類別「{0}」。

描述

#

當分析器遇到一個看起來像是類別名稱的識別符,但該識別符未被定義或在其被引用的範圍內不可見時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 Piont 未被定義

dart
class Point {}

void f(Piont p) {}

常見修正方式

#

如果識別符未被定義,則定義它或將其替換為已定義的類別名稱。上述範例可以透過修正類別的拼字來更正

dart
class Point {}

void f(Point p) {}

如果類別已定義但不可見,則您可能需要新增一個匯入。

初始化器中未定義的建構子

#

類別「{0}」沒有名為「{1}」的建構子。

類別 '{0}' 沒有未命名的建構子。

描述

#

當在建構子的初始化列表中呼叫超類別建構子時,但超類別未定義被呼叫的建構子,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 A 沒有未命名的建構子

dart
class A {
  A.n();
}
class B extends A {
  B() : super();
}

以下程式碼會產生此診斷訊息,因為 A 沒有名為 m 的建構子

dart
class A {
  A.n();
}
class B extends A {
  B() : super.m();
}

常見修正方式

#

如果超類別定義了一個應該被呼叫的建構子,則變更正在呼叫的建構子

dart
class A {
  A.n();
}
class B extends A {
  B() : super.n();
}

如果超類別未定義適當的建構子,則定義正在呼叫的建構子

dart
class A {
  A.m();
  A.n();
}
class B extends A {
  B() : super.m();
}

未定義的列舉常數

#

在「{1}」中沒有名為「{0}」的常數。

描述

#

當分析器遇到一個看起來像是列舉值的名稱的識別符,且該名稱未被定義或在其被引用的範圍內不可見時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 E 沒有定義名為 c 的常數

dart
enum E {a, b}

var e = E.c;

常見修正方式

#

如果應該定義常數,則將其新增到列舉的宣告中

dart
enum E {a, b, c}

var e = E.c;

如果不應該定義常數,則將名稱變更為現有常數的名稱

dart
enum E {a, b}

var e = E.b;

未定義的列舉建構子

#

列舉沒有名為「{0}」的建構子。

列舉沒有未命名的建構子。

描述

#

當呼叫用於初始化列舉值的建構子不存在時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列舉值 c 正由未命名的建構子初始化,但 E 中未定義未命名的建構子

dart
enum E {
  c();

  const E.x();
}

以下程式碼會產生此診斷訊息,因為列舉值 c 正由名為 x 的建構子初始化,但 E 中未定義名為 x 的建構子

dart
enum E {
  c.x();

  const E.y();
}

常見修正方式

#

如果列舉值正由未命名的建構子初始化,且應該使用其中一個命名的建構子,則新增建構子的名稱

dart
enum E {
  c.x();

  const E.x();
}

如果列舉值正由未命名的建構子初始化,且沒有任何命名的建構子是適當的,則定義未命名的建構子

dart
enum E {
  c();

  const E();
}

如果列舉值正由命名的建構子初始化,且應該使用其中一個現有的建構子,則變更正在呼叫的建構子的名稱(如果應該使用未命名的建構子,則移除它)

dart
enum E {
  c.y();

  const E();
  const E.y();
}

如果列舉值正由命名的建構子初始化,且沒有任何現有的建構子是適當的,則定義一個具有所使用名稱的建構子

dart
enum E {
  c.x();

  const E.x();
}

未定義的擴充功能_getter

#

擴充套件「{1}」未定義 getter「{0}」。

描述

#

當擴充套件覆寫被用於呼叫 getter,但指定的擴充套件未定義該 getter 時,分析器會產生此診斷訊息。當參考靜態 getter 但指定的擴充套件未定義該 getter 時,分析器也會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充套件 E 沒有宣告名為 b 的實例 getter

dart
extension E on String {
  String get a => 'a';
}

extension F on String {
  String get b => 'b';
}

void f() {
  E('c').b;
}

以下程式碼會產生此診斷訊息,因為擴充套件 E 沒有宣告名為 a 的靜態 getter

dart
extension E on String {}

var x = E.a;

常見修正方式

#

如果 getter 的名稱不正確,則將其變更為現有 getter 的名稱

dart
extension E on String {
  String get a => 'a';
}

extension F on String {
  String get b => 'b';
}

void f() {
  E('c').a;
}

如果 getter 的名稱正確,但擴充套件的名稱錯誤,則將擴充套件的名稱變更為正確的名稱

dart
extension E on String {
  String get a => 'a';
}

extension F on String {
  String get b => 'b';
}

void f() {
  F('c').b;
}

如果 getter 和擴充套件的名稱都正確,但未定義 getter,則定義 getter

dart
extension E on String {
  String get a => 'a';
  String get b => 'z';
}

extension F on String {
  String get b => 'b';
}

void f() {
  E('c').b;
}

未定義的擴充功能方法

#

擴充套件「{1}」未定義方法「{0}」。

描述

#

當擴充套件覆寫被用於呼叫方法,但指定的擴充套件未定義該方法時,分析器會產生此診斷訊息。當參考靜態方法但指定的擴充套件未定義該方法時,分析器也會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充套件 E 沒有宣告名為 b 的實例方法

dart
extension E on String {
  String a() => 'a';
}

extension F on String {
  String b() => 'b';
}

void f() {
  E('c').b();
}

以下程式碼會產生此診斷訊息,因為擴充套件 E 沒有宣告名為 a 的靜態方法

dart
extension E on String {}

var x = E.a();

常見修正方式

#

如果方法的名稱不正確,則將其變更為現有方法的名稱

dart
extension E on String {
  String a() => 'a';
}

extension F on String {
  String b() => 'b';
}

void f() {
  E('c').a();
}

如果方法的名稱正確,但擴充套件的名稱錯誤,則將擴充套件的名稱變更為正確的名稱

dart
extension E on String {
  String a() => 'a';
}

extension F on String {
  String b() => 'b';
}

void f() {
  F('c').b();
}

如果方法和擴充套件的名稱都正確,但未定義方法,則定義方法

dart
extension E on String {
  String a() => 'a';
  String b() => 'z';
}

extension F on String {
  String b() => 'b';
}

void f() {
  E('c').b();
}

未定義的擴充功能運算子

#

擴充套件「{1}」未定義運算子「{0}」。

描述

#

當在特定擴充套件上呼叫運算子,但該擴充套件未實作該運算子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充套件 E 未定義運算子 *

dart
var x = E('') * 4;

extension E on String {}

常見修正方式

#

如果預期擴充套件實作該運算子,則將該運算子的實作新增到擴充套件

dart
var x = E('') * 4;

extension E on String {
  int operator *(int multiplier) => length * multiplier;
}

如果運算子由不同的擴充套件定義,則將擴充套件的名稱變更為定義該運算子的擴充套件的名稱。

如果運算子在擴充套件覆寫的引數上定義,則移除擴充套件覆寫

dart
var x = '' * 4;

extension E on String {}

未定義的擴充功能_setter

#

擴充套件「{1}」未定義 setter「{0}」。

描述

#

當擴充套件覆寫被用於呼叫 setter,但指定的擴充套件未定義該 setter 時,分析器會產生此診斷訊息。當參考靜態 setter 但指定的擴充套件未定義該 setter 時,分析器也會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充套件 E 沒有宣告名為 b 的實例 setter

dart
extension E on String {
  set a(String v) {}
}

extension F on String {
  set b(String v) {}
}

void f() {
  E('c').b = 'd';
}

以下程式碼會產生此診斷訊息,因為擴充套件 E 沒有宣告名為 a 的靜態 setter

dart
extension E on String {}

void f() {
  E.a = 3;
}

常見修正方式

#

如果 setter 的名稱不正確,則將其變更為現有 setter 的名稱

dart
extension E on String {
  set a(String v) {}
}

extension F on String {
  set b(String v) {}
}

void f() {
  E('c').a = 'd';
}

如果 setter 的名稱正確,但擴充套件的名稱錯誤,則將擴充套件的名稱變更為正確的名稱

dart
extension E on String {
  set a(String v) {}
}

extension F on String {
  set b(String v) {}
}

void f() {
  F('c').b = 'd';
}

如果 setter 和擴充套件的名稱都正確,但未定義 setter,則定義 setter

dart
extension E on String {
  set a(String v) {}
  set b(String v) {}
}

extension F on String {
  set b(String v) {}
}

void f() {
  E('c').b = 'd';
}

未定義的函式

#

未定義函式「{0}」。

描述

#

當分析器遇到一個看起來像是函式名稱的識別符,但該識別符未被定義或在其被引用的範圍內不可見時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 emty 未被定義

dart
List<int> empty() => [];

void main() {
  print(emty());
}

常見修正方式

#

如果識別符未被定義,則定義它或將其替換為已定義的函式名稱。上述範例可以透過修正函式的拼字來更正

dart
List<int> empty() => [];

void main() {
  print(empty());
}

如果函式已定義但不可見,則您可能需要新增一個匯入或重新安排您的程式碼以使函式可見。

未定義的_getter

#

getter「{0}」未針對「{1}」函式類型定義。

getter「{0}」未針對類型「{1}」定義。

描述

#

當分析器遇到一個看起來像是 getter 名稱的識別符,但該識別符未被定義或在其被引用的範圍內不可見時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 String 沒有名為 len 的成員

dart
int f(String s) => s.len;

常見修正方式

#

如果識別符未被定義,則定義它或將其替換為已定義的 getter 名稱。上述範例可以透過修正 getter 的拼字來更正

dart
int f(String s) => s.length;

未定義的隱藏名稱

#

程式庫「{0}」沒有匯出具有隱藏名稱「{1}」的成員。

描述

#

當 hide 組合器包含一個未由正在匯入的程式庫定義的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 dart:math 沒有定義名稱 String

dart
import 'dart:math' hide String, max;

var x = min(0, 1);

常見修正方式

#

如果應該隱藏不同的名稱,則更正名稱。否則,從清單中移除該名稱

dart
import 'dart:math' hide max;

var x = min(0, 1);

未定義的識別項

#

未定義的名稱「{0}」。

描述

#

當分析器遇到一個未被定義或在其被引用的範圍內不可見的識別符時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 rihgt 未被定義

dart
int min(int left, int right) => left <= rihgt ? left : right;

常見修正方式

#

如果識別符未被定義,則定義它或將其替換為已定義的識別符。上述範例可以透過修正變數的拼字來更正

dart
int min(int left, int right) => left <= right ? left : right;

如果識別符已定義但不可見,則您可能需要新增一個匯入或重新安排您的程式碼以使識別符可見。

未定義的識別項_await

#

未標記 'async' 的函式主體中使用了未定義的名稱 'await'。

描述

#

當在方法或函式主體中使用名稱 await 而未宣告,且主體未標記 async 關鍵字時,分析器會產生此診斷訊息。名稱 await 僅在非同步函式中引入 await 運算式。

範例

#

以下程式碼會產生此診斷訊息,因為名稱 awaitf 的主體中使用,即使 f 的主體未標記 async 關鍵字

dart
void f(p) { await p; }

常見修正方式

#

將關鍵字 async 新增到函式主體

dart
void f(p) async { await p; }

未定義的方法

#

方法「{0}」未針對「{1}」函式類型定義。

方法「{0}」未針對類型「{1}」定義。

描述

#

當分析器遇到一個看起來像是方法名稱的識別符,但該識別符未被定義或在其被引用的範圍內不可見時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為識別符 removeMiddle 未被定義

dart
int f(List<int> l) => l.removeMiddle();

常見修正方式

#

如果識別符未被定義,則定義它或將其替換為已定義的方法名稱。上述範例可以透過修正方法的拼字來更正

dart
int f(List<int> l) => l.removeLast();

未定義的具名參數

#

未定義具名參數「{0}」。

描述

#

當方法或函式調用具有具名引數,但被調用的方法或函式未定義具有相同名稱的參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 m 沒有宣告名為 a 的具名參數

dart
class C {
  m({int? b}) {}
}

void f(C c) {
  c.m(a: 1);
}

常見修正方式

#

如果引數名稱拼寫錯誤,則將其替換為正確的名稱。上述範例可以透過將 a 變更為 b 來修正

dart
class C {
  m({int? b}) {}
}

void f(C c) {
  c.m(b: 1);
}

如果子類別新增了一個具有問題名稱的參數,則將接收器轉換為子類別

dart
class C {
  m({int? b}) {}
}

class D extends C {
  m({int? a, int? b}) {}
}

void f(C c) {
  (c as D).m(a: 1);
}

如果應該將參數新增到函式,則新增它

dart
class C {
  m({int? a, int? b}) {}
}

void f(C c) {
  c.m(a: 1);
}

未定義的運算子

#

運算子「{0}」未針對類型「{1}」定義。

描述

#

當在未定義運算子的物件上調用使用者可定義的運算子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 未定義運算子 +

dart
class C {}

C f(C c) => c + 2;

常見修正方式

#

如果應該為類別定義運算子,則定義它

dart
class C {
  C operator +(int i) => this;
}

C f(C c) => c + 2;

未定義的前置詞名稱

#

名稱「{0}」正透過前綴「{1}」被參考,但它未在任何使用該前綴匯入的程式庫中定義。

描述

#

當找到帶有前綴的識別符,且前綴有效,但該識別符未在任何使用該前綴匯入的程式庫中宣告時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 dart:core 沒有定義任何名為 a 的內容

dart
import 'dart:core' as p;

void f() {
  p.a;
}

常見修正方式

#

如果宣告名稱的程式庫尚未匯入,則為該程式庫新增一個匯入。

如果名稱錯誤,則將其變更為在匯入的程式庫中宣告的名稱之一。

未定義的參考參數

#

參數「{0}」未由「{1}」定義。

描述

#

UseResult.unless(parameterDefined: parameterName) 形式的註解指定一個未由帶註解的函式定義的參數名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函式 f 沒有名為 b 的參數

dart
import 'package:meta/meta.dart';

@UseResult.unless(parameterDefined: 'b')
int f([int? a]) => a ?? 0;

常見修正方式

#

變更名為 parameterDefined 的引數以符合函式的其中一個參數的名稱

dart
import 'package:meta/meta.dart';

@UseResult.unless(parameterDefined: 'a')
int f([int? a]) => a ?? 0;

未定義的_setter

#

setter「{0}」未針對「{1}」函式類型定義。

setter「{0}」未針對類型「{1}」定義。

描述

#

當分析器遇到一個看起來像是 setter 名稱的識別符,但該識別符未被定義或在其被引用的範圍內不可見時,會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為沒有名為 z 的 setter

dart
class C {
  int x = 0;
  void m(int y) {
    this.z = y;
  }
}

常見修正方式

#

如果識別符未被定義,則定義它或將其替換為已定義的 setter 名稱。上述範例可以透過修正 setter 的拼字來更正

dart
class C {
  int x = 0;
  void m(int y) {
    this.x = y;
  }
}

未定義的顯示名稱

#

程式庫「{0}」沒有匯出具有顯示名稱「{1}」的成員。

描述

#

當 show 組合器包含一個未由正在匯入的程式庫定義的名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 dart:math 沒有定義名稱 String

dart
import 'dart:math' show min, String;

var x = min(0, 1);

常見修正方式

#

如果應該顯示不同的名稱,則更正名稱。否則,從清單中移除該名稱

dart
import 'dart:math' show min;

var x = min(0, 1);

未定義的_super_成員

#

(先前稱為 undefined_super_method)

getter「{0}」未在「{1}」的超類別中定義。

方法「{0}」未在「{1}」的超類別中定義。

運算子「{0}」未在「{1}」的超類別中定義。

setter「{0}」未在「{1}」的超類別中定義。

描述

#

當使用 super 參考繼承的成員(方法、getter、setter 或運算子),但在超類別鏈中沒有具有該名稱的成員時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 Object 沒有定義名為 n 的方法

dart
class C {
  void m() {
    super.n();
  }
}

以下程式碼會產生此診斷訊息,因為 Object 沒有定義名為 g 的 getter

dart
class C {
  void m() {
    super.g;
  }
}

常見修正方式

#

如果您打算調用的繼承成員具有不同的名稱,則使調用的成員的名稱與繼承成員的名稱相符。

如果您打算調用的成員在同一個類別中定義,則移除 super.

如果未定義成員,則將成員新增到其中一個超類別或移除調用。

未知的平台

#

平台「{0}」不是可辨識的平台。

描述

#

當在 platforms 映射中使用未知的平台名稱作為鍵時,分析器會產生此診斷訊息。若要進一步瞭解如何指定套件支援的平台,請查看關於平台宣告的文件

範例

#

以下 pubspec.yaml 會產生此診斷訊息,因為平台 browser 是未知的。

yaml
name: example
platforms:
  browser:

常見修正方式

#

如果您可以依賴自動平台偵測,則省略最上層的 platforms 鍵。

yaml
name: example

如果您需要手動指定支援平台的清單,則將 platforms 欄位寫為以已知平台名稱作為鍵的映射。

yaml
name: example
platforms:
  # These are the known platforms
  android:
  ios:
  linux:
  macos:
  web:
  windows:

不必要的轉換

#

不必要的轉型。

描述

#

當要轉換的值已知已為要轉換成的類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為由於 is 測試,n 已知為 int

dart
void f(num n) {
  if (n is int) {
    (n as int).isEven;
  }
}

常見修正方式

#

移除不必要的轉換。

dart
void f(num n) {
  if (n is int) {
    n.isEven;
  }
}

不必要的開發相依性

#

在 {0} 上的開發相依性是不必要的,因為在該套件上也有正常的相依性。

描述

#

dev_dependencies 下有一個條目,用於也列在 dependencies 下的套件時,分析器會產生此診斷訊息。dependencies 下的套件可用於套件中的所有程式碼,因此不需要也將它們列在 dev_dependencies 下。

範例

#

以下程式碼會產生此診斷訊息,因為套件 meta 同時列在 dependenciesdev_dependencies

yaml
name: example
dependencies:
  meta: ^1.0.2
dev_dependencies:
  meta: ^1.0.2

常見修正方式

#

移除 dev_dependencies 下的條目(如果那是唯一列出的套件,則移除 dev_dependencies 鍵)

yaml
name: example
dependencies:
  meta: ^1.0.2

不必要的_final

#

關鍵字 'final' 是不必要的,因為參數隱含地是 'final'。

描述

#

當建構子中的欄位初始化參數或超參數具有關鍵字 final 時,分析器會產生此診斷訊息。在這兩種情況下,關鍵字都是不必要的,因為參數隱含地是 final

範例

#

以下程式碼會產生此診斷訊息,因為欄位初始化參數具有關鍵字 final

dart
class A {
  int value;

  A(final this.value);
}

以下程式碼會產生此診斷訊息,因為 B 中的超參數具有關鍵字 final

dart
class A {
  A(int value);
}

class B extends A {
  B(final super.value);
}

常見修正方式

#

移除不必要的 final 關鍵字

dart
class A {
  A(int value);
}

class B extends A {
  B(super.value);
}

不必要的匯入

#

匯入 '{0}' 是不必要的,因為所有使用的元素也由匯入 '{1}' 提供。

描述

#

當不需要匯入時,分析器會產生此診斷訊息,因為所有匯入且在匯入程式庫中被參考的名稱也透過另一個匯入可見。

範例

#

給定一個包含以下內容的檔案 a.dart

dart
class A {}

並且,給定一個包含以下內容的檔案 b.dart

dart
export 'a.dart';

class B {}

以下程式碼會產生此診斷訊息,因為從 a.dart 匯入的類別 A 也從 b.dart 匯入。移除匯入 a.dart 不會改變語意

dart
import 'a.dart';
import 'b.dart';

void f(A a, B b) {}

常見修正方式

#

如果不需要匯入,則移除它。

如果此匯入所匯入的某些名稱打算使用但尚未被使用,並且如果這些名稱未由其他匯入匯入,則新增對這些名稱的遺失參考。

不必要的_NaN比較

#

double 無法等於 'double.nan',因此條件永遠為 'false'。

double 無法等於 'double.nan',因此條件永遠為 'true'。

描述

#

當使用 ==!= 將值與 double.nan 比較時,分析器會產生此診斷訊息。

Dart 遵循 IEEE 754 浮點標準,用於浮點運算的語意,該標準指出,對於任何浮點值 x(包括 NaN、正無限和負無限),

  • NaN == x 永遠為 false
  • NaN != x 永遠為 true

因此,將任何值與 NaN 比較是沒有意義的,因為結果已經已知(基於所使用的比較運算子)。

範例

#

以下程式碼會產生此診斷訊息,因為 d 正與 double.nan 比較

dart
bool isNaN(double d) => d == double.nan;

常見修正方式

#

改用 getter double.isNaN

dart
bool isNaN(double d) => d.isNaN;

不必要的非空值斷言

#

'!' 將不起作用,因為接收器不能為 null。

描述

#

! 運算子的運算元不能為 null 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷,因為 x 不可為 null

dart
int f(int x) {
  return x!;
}

常見修正方式

#

移除 null 檢查運算子 (!)

dart
int f(int x) {
  return x;
}

不必要的_noSuchMethod

#

不必要的 'noSuchMethod' 宣告。

描述

#

當存在 noSuchMethod 的宣告,而宣告唯一做的事情是調用覆寫的宣告,且覆寫的宣告不是 Object 中的宣告時,分析器會產生此診斷訊息。

覆寫 ObjectnoSuchMethod 的實作(無論實作做什麼)向分析器發出訊號,表明它不應標記任何未在該類別中實作的繼承抽象方法。即使覆寫的實作是從超類別繼承的,這也有效,因此在子類別中再次宣告它沒有價值。

範例

#

以下程式碼會產生此診斷訊息,因為 A 中的 noSuchMethod 宣告使 B 中的 noSuchMethod 宣告變得不必要

dart
class A {
  @override
  dynamic noSuchMethod(x) => super.noSuchMethod(x);
}
class B extends A {
  @override
  dynamic noSuchMethod(y) {
    return super.noSuchMethod(y);
  }
}

常見修正方式

#

移除不必要的宣告

dart
class A {
  @override
  dynamic noSuchMethod(x) => super.noSuchMethod(x);
}
class B extends A {}

不必要的_null_斷言模式

#

null-assert 模式將不起作用,因為比對的類型不可為 null。

描述

#

當 null-assert 模式用於比對不可為 null 的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為變數 x 不可為 null

dart
void f(int x) {
  if (x case var a! when a > 0) {}
}

常見修正方式

#

移除 null-assert 模式

dart
void f(int x) {
  if (x case var a when a > 0) {}
}

不必要的_null_檢查模式

#

null-check 模式將不起作用,因為比對的類型不可為 null。

描述

#

當 null-check 模式用於比對不可為 null 的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為值 x 不可為 null

dart
void f(int x) {
  if (x case var a? when a > 0) {}
}

常見修正方式

#

移除 null-check 模式

dart
void f(int x) {
  if (x case var a when a > 0) {}
}

不必要的_null比較

#

運算元不能為 'null',因此條件永遠為 'false'。

運算元不能為 'null',因此條件永遠為 'true'。

運算元必須為 'null',因此條件永遠為 'false'。

運算元必須為 'null',因此條件永遠為 'true'。

描述

#

當分析器找到一個與 null 進行等式比較(==!=),且另一個運算元不能為 null 時,會產生此診斷訊息。這樣的比較始終為 truefalse,因此它們沒有任何意義。

範例

#

以下程式碼會產生此診斷訊息,因為 x 永遠不能為 null,因此比較始終評估為 true

dart
void f(int x) {
  if (x != null) {
    print(x);
  }
}

以下程式碼會產生此診斷訊息,因為 x 永遠不能為 null,因此比較始終評估為 false

dart
void f(int x) {
  if (x == null) {
    throw ArgumentError("x can't be null");
  }
}

常見修正方式

#

如果另一個運算元應該能夠為 null,則變更運算元的類型

dart
void f(int? x) {
  if (x != null) {
    print(x);
  }
}

如果另一個運算元確實不能為 null,則移除條件

dart
void f(int x) {
  print(x);
}

不必要的問號

#

'?' 是不必要的,因為沒有它,「{0}」也是可為 null 的。

描述

#

當類型 dynamic 或類型 Null 後面跟著問號時,分析器會產生此診斷訊息。這兩種類型本身都是可為 null 的,因此問號不會改變語意。

範例

#

以下程式碼會產生此診斷訊息,因為 dynamic 後面的問號是不必要的

dart
dynamic? x;

常見修正方式

#

移除不必要的問號

dart
dynamic x;

不必要的_set_字面值

#

大括號不必要地將此運算式包裝在集合字面值中。

描述

#

當具有 voidFuture<void>FutureOr<void> 回傳類型的函式使用運算式函式主體 (=>) 且回傳值是包含單一元素的字面值集合時,分析器會產生此診斷訊息。

雖然語言允許,但從 void 函式回傳值是沒有用的,因為它不能在呼叫點使用。在這種特定情況下,回傳通常是由於對語法的誤解。大括號是不必要的,可以移除。

範例

#

以下程式碼會產生此診斷訊息,因為傳遞給 g 的閉包的回傳類型為 void,但正在回傳一個集合

dart
void f() {
  g(() => {1});
}

void g(void Function() p) {}

常見修正方式

#

從值周圍移除大括號

dart
void f() {
  g(() => 1);
}

void g(void Function() p) {}

不必要的類型檢查

#

不必要的類型檢查;結果永遠為 'false'。

不必要的類型檢查;結果永遠為 'true'。

描述

#

當類型檢查的值(使用 isis!)在編譯時已知時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為測試 a is Object? 永遠為 true

dart
bool f<T>(T a) => a is Object?;

常見修正方式

#

如果類型檢查未檢查您打算檢查的內容,則變更測試

dart
bool f<T>(T a) => a is Object;

如果類型檢查確實檢查了您打算檢查的內容,則將類型檢查替換為其已知值或完全移除它

dart
bool f<T>(T a) => true;

對非本機靜態成員的不合格參考

#

來自超類型的靜態成員必須以定義類型的名稱限定。

描述

#

當一個類別中的程式碼參考超類別中的靜態成員,而沒有在成員名稱前加上超類別的名稱時,分析器會產生此診斷訊息。靜態成員只能在宣告它們的類別中無前綴地被參考。

範例

#

以下程式碼會產生此診斷訊息,因為靜態欄位 x 在 getter g 中被參考,而沒有在其前面加上定義類別的名稱

dart
class A {
  static int x = 3;
}

class B extends A {
  int get g => x;
}

常見修正方式

#

在靜態成員的名稱前加上宣告類別的名稱

dart
class A {
  static int x = 3;
}

class B extends A {
  int get g => A.x;
}

對擴充類型靜態成員的不合格參考

#

來自擴充類型或其超類別之一的靜態成員必須以定義類型的名稱限定。

描述

#

當找到未定義的名稱,且該名稱與擴充類型或其超類別之一的靜態成員相同時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 m 是擴充類型 C 的靜態成員

dart
class C {
  static void m() {}
}

extension E on C {
  void f() {
    m();
  }
}

常見修正方式

#

如果您嘗試參考在擴充套件外部宣告的靜態成員,則在成員的參考之前新增類別或擴充套件的名稱

dart
class C {
  static void m() {}
}

extension E on C {
  void f() {
    C.m();
  }
}

如果您正在參考尚未宣告的成員,則新增宣告

dart
class C {
  static void m() {}
}

extension E on C {
  void f() {
    m();
  }

  void m() {}
}

無法連線的_switch_case

#

此情況已包含在先前的案例中。

描述

#

switch 語句中的 case 子句不比對任何內容,因為所有可比對的值都已由較早的 case 子句比對時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為值 1 已在前一個案例中比對

dart
void f(int x) {
  switch (x) {
    case 1:
      print('one');
    case 1:
      print('two');
  }
}

常見修正方式

#

變更其中一個或兩個衝突的案例以比對不同的值

dart
void f(int x) {
  switch (x) {
    case 1:
      print('one');
    case 2:
      print('two');
  }
}

無法連線的_switch_default

#

此 default 子句已包含在先前的案例中。

描述

#

switch 語句中的 default 子句不比對任何內容,因為所有可比對的值都已由較早的 case 子句比對時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為值 E.e1E.e2 已在前述案例中比對

dart
enum E { e1, e2 }

void f(E x) {
  switch (x) {
    case E.e1:
      print('one');
    case E.e2:
      print('two');
    default:
      print('other');
  }
}

常見修正方式

#

移除不必要的 default 子句

dart
enum E { e1, e2 }
void f(E x) {
  switch (x) {
    case E.e1:
      print('one');
    case E.e2:
      print('two');
  }
}

未使用的_catch_子句

#

例外變數「{0}」未使用,因此可以移除 'catch' 子句。

描述

#

當找到 catch 子句,且異常參數和可選的堆疊追蹤參數都未在 catch 區塊中使用時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 e 未被參考

dart
void f() {
  try {
    int.parse(';');
  } on FormatException catch (e) {
    // ignored
  }
}

常見修正方式

#

移除未使用的 catch 子句

dart
void f() {
  try {
    int.parse(';');
  } on FormatException {
    // ignored
  }
}

未使用的_catch堆疊

#

堆疊追蹤變數「{0}」未使用,可以移除。

描述

#

catch 子句中的堆疊追蹤參數未在 catch 區塊的主體中被參考時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 stackTrace 未被參考

dart
void f() {
  try {
    // ...
  } catch (exception, stackTrace) {
    // ...
  }
}

常見修正方式

#

如果您需要參考堆疊追蹤參數,則新增對它的參考。否則,移除它

dart
void f() {
  try {
    // ...
  } catch (exception) {
    // ...
  }
}

未使用的元素

#

宣告「{0}」未被參考。

描述

#

當私有宣告未在其包含宣告的程式庫中被參考時,分析器會產生此診斷訊息。分析以下幾種宣告

  • 私有最上層宣告及其所有成員
  • 公有宣告的私有成員

並非所有對元素的參考都會將其標記為「已使用」

  • 為最上層變數賦值(使用標準 = 賦值或可為 null 的 ??= 賦值)不計為使用它。
  • 在文件註解參考中參考元素不計為使用它。
  • is 運算式右側參考類別、mixin 或列舉不計為使用它。

範例

#

假設程式庫中沒有程式碼參考 _C,以下程式碼會產生此診斷訊息

dart
class _C {}

常見修正方式

#

如果不需要宣告,則移除它。

如果宣告的目的是被使用,則新增程式碼以使用它。

未使用的元素參數

#

永遠不會為可選參數「{0}」提供值。

描述

#

當永遠不會為私有宣告中宣告的可選參數傳遞值時,分析器會產生此診斷訊息。

範例

#

假設程式庫中沒有程式碼在任何 _m 的調用中為 y 傳遞值,以下程式碼會產生此診斷訊息

dart
class C {
  void _m(int x, [int? y]) {}

  void n() => _m(0);
}

常見修正方式

#

如果不需要宣告,則移除它

dart
class C {
  void _m(int x) {}

  void n() => _m(0);
}

如果宣告的目的是被使用,則新增程式碼以使用它。

未使用的欄位

#

未使用欄位「{0}」的值。

描述

#

當宣告了私有欄位但從未讀取,即使它在一個或多個位置被寫入時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 _originalValue 在程式庫中的任何地方都未被讀取

dart
class C {
  final String _originalValue;
  final String _currentValue;

  C(this._originalValue) : _currentValue = _originalValue;

  String get value => _currentValue;
}

看起來欄位 _originalValue 正在初始化器中被讀取 (_currentValue = _originalValue),但那實際上是對同名參數的參考,而不是對欄位的參考。

常見修正方式

#

如果不需要欄位,則移除它。

如果欄位的目的是被使用,則新增遺失的程式碼。

未使用的匯入

#

未使用的匯入:「{0}」。

描述

#

當不需要匯入時,分析器會產生此診斷訊息,因為沒有任何匯入的名稱在匯入程式庫中被參考。

範例

#

以下程式碼會產生此診斷訊息,因為在程式庫中沒有參考 dart:async 中定義的任何內容

dart
import 'dart:async';

void main() {}

常見修正方式

#

如果不需要匯入,則移除它。

如果打算使用某些匯入的名稱,則新增遺失的程式碼。

未使用的標籤

#

標籤「{0}」未使用。

描述

#

當找到未使用的標籤時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為標籤 loop 未在方法中的任何地方被參考

dart
void f(int limit) {
  loop: for (int i = 0; i < limit; i++) {
    print(i);
  }
}

常見修正方式

#

如果不需要標籤,則移除它

dart
void f(int limit) {
  for (int i = 0; i < limit; i++) {
    print(i);
  }
}

如果需要標籤,則使用它

dart
void f(int limit) {
  loop: for (int i = 0; i < limit; i++) {
    print(i);
    if (i != 0) {
      break loop;
    }
  }
}

未使用的區域變數

#

未使用區域變數「{0}」的值。

描述

#

當宣告了區域變數但從未讀取,即使它在一個或多個位置被寫入時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 count 的值從未被讀取

dart
void main() {
  int count = 0;
}

常見修正方式

#

如果不需要變數,則移除它。

如果變數的目的是被使用,則新增遺失的程式碼。

未使用的結果

#

應該使用「{0}」。{1}。

應該使用「{0}」的值。

描述

#

當調用了使用 useResult 註解的函式,且未使用該函式回傳的值時,分析器會產生此診斷訊息。如果調用了值的成員、如果值傳遞給另一個函式,或者如果值賦值給變數或欄位,則該值被視為已使用。

範例

#

以下程式碼會產生此診斷訊息,因為 c.a() 的調用未使用,即使方法 a 使用 useResult 註解

dart
import 'package:meta/meta.dart';

class C {
  @useResult
  int a() => 0;

  int b() => 0;
}

void f(C c) {
  c.a();
}

常見修正方式

#

如果您打算調用帶註解的函式,則使用回傳的值

dart
import 'package:meta/meta.dart';

class C {
  @useResult
  int a() => 0;

  int b() => 0;
}

void f(C c) {
  print(c.a());
}

如果您打算調用不同的函式,則更正正在調用的函式名稱

dart
import 'package:meta/meta.dart';

class C {
  @useResult
  int a() => 0;

  int b() => 0;
}

void f(C c) {
  c.b();
}

未使用的顯示名稱

#

名稱 {0} 已顯示,但未使用。

描述

#

當 show 組合器包含一個未在程式庫中使用的名稱時,分析器會產生此診斷訊息。因為它未被參考,所以可以移除該名稱。

範例

#

以下程式碼會產生此診斷訊息,因為函式 max 未被使用

dart
import 'dart:math' show min, max;

var x = min(0, 1);

常見修正方式

#

使用該名稱或移除它

dart
import 'dart:math' show min;

var x = min(0, 1);

URI不存在

#

URI 的目標不存在:「{0}」。

描述

#

當找到 import、export 或 part 指令,且 URI 指向不存在的檔案時,分析器會產生此診斷訊息。

範例

#

如果檔案 lib.dart 不存在,則以下程式碼會產生此診斷訊息

dart
import 'lib.dart';

常見修正方式

#

如果 URI 拼寫錯誤或無效,則更正 URI。

如果 URI 正確,則建立檔案。

文件匯入中_URI不存在

#

URI 的目標不存在:「{0}」。

描述

#

當找到 doc-import,且 URI 指向不存在的檔案時,分析器會產生此診斷訊息。

範例

#

如果檔案 lib.dart 不存在,則以下程式碼會產生此診斷訊息

dart
/// @docImport 'lib.dart';
library;

常見修正方式

#

如果 URI 拼寫錯誤或無效,則更正 URI。

如果 URI 正確,則建立檔案。

URI尚未產生

#

URI 的目標尚未產生:「{0}」。

描述

#

當找到 import、export 或 part 指令,且 URI 指向不存在的檔案,且檔案名稱以程式碼產生器常用的模式結尾時,分析器會產生此診斷訊息,例如以下之一

  • .g.dart
  • .pb.dart
  • .pbenum.dart
  • .pbserver.dart
  • .pbjson.dart
  • .template.dart

範例

#

如果 lib.g.dart 檔案不存在,以下程式碼會產生此診斷訊息

dart
import 'lib.g.dart';

常見修正方式

#

如果檔案是產生出來的檔案,那麼請執行產生該檔案的產生器。

如果檔案不是產生出來的檔案,那麼請檢查 URI 的拼寫或建立檔案。

具有內插的_URI

#

URI 不能使用字串插值。

描述

#

importexportpart 指令中的字串字面值包含插值時,分析器會產生此診斷訊息。指令中 URI 的解析必須在宣告編譯之前發生,因此在決定 URI 的值時無法評估表達式。

範例

#

以下程式碼會產生此診斷訊息,因為 import 指令中的字串包含插值

dart
import 'dart:$m';

const m = 'math';

常見修正方式

#

從 URI 中移除插值

dart
import 'dart:math';

var zero = min(0, 0);

原生擴充功能的使用

#

Dart 原生擴充功能已棄用,且在 Dart 2.15 中不可用。

描述

#

當使用 dart-ext 方案匯入程式庫時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為原生程式庫 x 正使用 dart-ext 方案匯入

dart
import 'dart-ext:x';

常見修正方式

#

重寫程式碼以使用 dart:ffi 作為呼叫原生程式庫內容的方式。

void結果的使用

#

此表達式的類型為 'void',因此其值無法使用。

描述

#

當分析器找到類型為 void 的表達式,且該表達式用在期望值的地方時 (例如在成員存取之前或賦值運算子的右側),就會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 f 沒有產生可以呼叫 toString 的物件

dart
void f() {}

void g() {
  f().toString();
}

常見修正方式

#

可以重寫程式碼,使表達式具有值,或者重寫程式碼,使其不依賴該值。

列舉中的值宣告

#

名為 'values' 的成員不能在列舉中宣告。

描述

#

當列舉宣告定義名為 values 的成員時 (無論該成員是列舉值、實例成員或靜態成員),分析器會產生此診斷訊息。

任何此類成員都會與靜態 getter values 的隱式宣告衝突,後者會傳回包含所有列舉常數的列表。

範例

#

以下程式碼會產生此診斷訊息,因為列舉 E 定義了名為 values 的實例成員

dart
enum E {
  v;
  void values() {}
}

常見修正方式

#

變更衝突成員的名稱

dart
enum E {
  v;
  void getValues() {}
}

變長陣列不是最後一個

#

變長 'Array' 只能作為 Structs 的最後一個欄位出現。

描述

#

當變長內聯 Array 不是 Struct 的最後一個成員時,分析器會產生此診斷訊息。

有關 FFI 的更多資訊,請參閱 使用 dart:ffi 的 C 互操作

範例

#

以下程式碼會產生此診斷訊息,因為欄位 a0 的類型具有三個巢狀陣列,但在 Array 註解中僅給定兩個維度。

dart
import 'dart:ffi';

final class C extends Struct {
  @Array.variable()
  external Array<Uint8> a0;

  @Uint8()
  external int a1;
}

常見修正方式

#

將變長內聯 Array 移動到 struct 中的最後一個欄位。

dart
import 'dart:ffi';

final class C extends Struct {
  @Uint8()
  external int a1;

  @Array.variable()
  external Array<Uint8> a0;
}

如果內聯陣列具有固定大小,請使用大小來註解它

dart
import 'dart:ffi';

final class C extends Struct {
  @Array(10)
  external Array<Uint8> a0;

  @Uint8()
  external int a1;
}

宣告情境中的變數模式關鍵字

#

宣告上下文中的變數模式不能指定 'var' 或 'final' 關鍵字。

描述

#

當在宣告上下文中使用變數模式時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為記錄模式中的變數模式位於宣告上下文中

dart
void f((int, int) r) {
  var (var x, y) = r;
  print(x + y);
}

常見修正方式

#

移除變數模式中的 varfinal 關鍵字。

dart
void f((int, int) r) {
  var (x, y) = r;
  print(x + y);
}

變數類型不符

#

類型為 '{0}' 的值無法賦值給類型為 '{1}' 的 const 變數。

描述

#

當常數表達式的求值會導致 CastException 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 x 的值是 int,無法賦值給 y,因為 int 不是 String

dart
const dynamic x = 0;
const String y = x;

常見修正方式

#

如果常數的宣告是正確的,那麼將賦值的值更改為正確的類型。

dart
const dynamic x = 0;
const String y = '$x';

如果賦值的值是正確的,那麼更改宣告以具有正確的類型。

dart
const int x = 0;
const int y = x;

工作區欄位不是清單

#

'workspace' 欄位的值必須是相對檔案路徑的列表。

描述

#

workspace 鍵的值不是列表時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為當期望是列表時,workspace 鍵的值卻是字串

yaml
name: example
workspace: notPaths

常見修正方式

#

更改 workspace 欄位的值,使其成為列表。

yaml
name: example
workspace:
    - pkg/package_1
    - pkg/package_2

工作區值不是字串

#

Workspace 條目必須是目錄路徑 (字串)。

描述

#

workspace 列表包含不是字串的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 workspace 列表包含一個 map

yaml
name: example
workspace:
    - image.gif: true

常見修正方式

#

更改 workspace 列表,使其僅包含有效的 POSIX 樣式目錄路徑。

yaml
name: example
workspace:
    - pkg/package_1
    - pkg/package_2

工作區值不是子目錄

#

Workspace 值必須是 '{0}' 子目錄的相對路徑。

描述

#

workspace 列表包含的值不是包含 `pubspec.yaml` 檔案的目錄的子目錄時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 workspace 列表中的值不是包含 'pubspec.yaml' 檔案的目錄的子目錄的相對路徑

yaml
name: example
workspace:
    - /home/my_package

常見修正方式

#

更改 workspace 列表,使其僅包含子目錄路徑。

yaml
name: example
workspace:
    - pkg/package_1
    - pkg/package_2

運算子的參數數量錯誤

#

運算子 '-' 應該宣告 0 或 1 個參數,但找到 {0} 個。

運算子 '{0}' 應該宣告正好 {1} 個參數,但找到 {2} 個。

描述

#

當運算子的宣告具有錯誤的參數數量時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為運算子 + 必須有一個對應於右運算元的單一參數

dart
class C {
  int operator +(a, b) => 0;
}

常見修正方式

#

新增或移除參數以符合所需的數量。

dart
class C {
  int operator +(a) => 0;
}

setter的參數數量錯誤

#

Setter 必須宣告正好一個必要的位置參數。

描述

#

當找到未宣告正好一個必要位置參數的 setter 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 setter s 宣告了兩個必要參數

dart
class C {
  set s(int x, int y) {}
}

以下程式碼會產生此診斷訊息,因為 setter s 宣告了一個可選參數

dart
class C {
  set s([int? x]) {}
}

常見修正方式

#

更改宣告,使其正好有一個必要的位置參數。

dart
class C {
  set s(int x) {}
}

類型引數數量錯誤

#

類型 '{0}' 宣告了 {1} 個類型參數,但給定了 {2} 個類型引數。

描述

#

當使用具有類型參數的類型並提供類型引數時,但類型引數的數量與類型參數的數量不同時,分析器會產生此診斷訊息。

當調用建構子且類型引數的數量與為類別宣告的類型參數的數量不符時,分析器也會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 C 有一個類型參數,但在用作類型註解時卻提供了兩個類型引數

dart
class C<E> {}

void f(C<int, int> x) {}

以下程式碼會產生此診斷訊息,因為 C 宣告了一個類型參數,但在建立實例時卻提供了兩個類型引數

dart
class C<E> {}

var c = C<int, int>();

常見修正方式

#

根據需要新增或移除類型引數,以符合為類型定義的類型參數的數量。

dart
class C<E> {}

void f(C<int> x) {}

建構子的類型引數數量錯誤

#

建構子 '{0}.{1}' 沒有類型參數。

描述

#

當在具名建構子的名稱後提供類型引數時,分析器會產生此診斷訊息。建構子無法宣告類型參數,因此調用只能提供與類別相關聯的類型引數,並且這些類型引數必須跟在類別名稱之後,而不是建構子名稱之後。

範例

#

以下程式碼會產生此診斷訊息,因為類型參數 (<String>) 跟在建構子名稱之後,而不是類別名稱之後

dart
class C<T> {
  C.named();
}
C f() => C.named<String>();

常見修正方式

#

如果類型引數是用於類別的類型參數,那麼將類型引數移動到類別名稱之後。

dart
class C<T> {
  C.named();
}
C f() => C<String>.named();

如果類型引數不是用於類別的類型參數,那麼移除它們。

dart
class C<T> {
  C.named();
}
C f() => C.named();

列舉的類型引數數量錯誤

#

列舉宣告了 {0} 個類型參數,但給定了 {1} 個類型引數。

描述

#

當實例化具有類型參數的列舉中的列舉值並提供類型引數時,但類型引數的數量與類型參數的數量不同時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列舉值 c 提供了一個類型引數,即使列舉 E 被宣告為具有兩個類型參數

dart
enum E<T, U> {
  c<int>()
}

常見修正方式

#

如果類型參數的數量是正確的,那麼更改類型引數的數量以符合類型參數的數量。

dart
enum E<T, U> {
  c<int, String>()
}

如果類型引數的數量是正確的,那麼更改類型參數的數量以符合類型引數的數量。

dart
enum E<T> {
  c<int>()
}

擴充功能的類型引數數量錯誤

#

擴充功能 '{0}' 宣告了 {1} 個類型參數,但給定了 {2} 個類型引數。

描述

#

當使用具有類型參數的擴充功能並提供類型引數時,但類型引數的數量與類型參數的數量不同時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充功能 E 被宣告為具有單一類型參數 (`T`),但擴充功能覆寫卻有兩個類型引數

dart
extension E<T> on List<T> {
  int get len => length;
}

void f(List<int> p) {
  E<int, String>(p).len;
}

常見修正方式

#

更改類型引數,使類型引數的數量與類型參數的數量相同。

dart
extension E<T> on List<T> {
  int get len => length;
}

void f(List<int> p) {
  E<int>(p).len;
}

方法的類型引數數量錯誤

#

方法 '{0}' 宣告了 {1} 個類型參數,但給定了 {2} 個類型引數。

描述

#

當調用方法或函式時,類型引數的數量與其宣告中指定的類型參數的數量不同時,分析器會產生此診斷訊息。必須沒有類型引數,或者引數的數量必須與參數的數量相符。

範例

#

以下程式碼會產生此診斷訊息,因為方法 `m` 的調用具有兩個類型引數,但 `m` 的宣告僅有一個類型參數

dart
class C {
  int m<A>(A a) => 0;
}

int f(C c) => c.m<int, int>(2);

常見修正方式

#

如果類型引數是必要的,那麼通過新增或移除類型引數使其符合類型參數的數量。

dart
class C {
  int m<A>(A a) => 0;
}

int f(C c) => c.m<int>(2);

如果類型引數不是必要的,那麼移除它們。

dart
class C {
  int m<A>(A a) => 0;
}

int f(C c) => c.m(2);

非產生器中的_yield

#

Yield 語句必須在產生器函式中 (標記為 'async*' 或 'sync*' 的函式)。

Yield-each 語句必須在產生器函式中 (標記為 'async*' 或 'sync*' 的函式)。

描述

#

當 `yield` 或 `yield*` 語句出現在主體未標記為 `async*` 或 `sync*` 修飾符之一的函式中時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `yield` 正在主體沒有修飾符的函式中使用

dart
Iterable<int> get digits {
  yield* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}

以下程式碼會產生此診斷訊息,因為 `yield*` 正在主體具有 `async` 修飾符而不是 `async*` 修飾符的函式中使用

dart
Stream<int> get digits async {
  yield* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}

常見修正方式

#

新增修飾符,或將現有的修飾符更改為 `async*` 或 `sync*`。

dart
Iterable<int> get digits sync* {
  yield* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}

無效類型的_yield

#

類型為 '{0}' 的 yielded 值必須可賦值給 '{1}'。

'yield*' 表達式所暗示的類型 '{0}' 必須可賦值給 '{1}'。

描述

#

當 `yield` 或 `yield*` 表達式產生的物件類型與要從產生器 (標記為 `sync*` 或 `async*` 的函式或方法) 傳回的 `Iterable` 或 `Stream` 類型傳回的物件類型不符時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 getter `zero` 被宣告為傳回一個傳回整數的 `Iterable`,但 `yield` 正從 iterable 傳回一個字串

dart
Iterable<int> get zero sync* {
  yield '0';
}

常見修正方式

#

如果函式的傳回類型是正確的,那麼修正關鍵字 `yield` 後面的表達式以傳回正確的類型。

dart
Iterable<int> get zero sync* {
  yield 0;
}

如果 `yield` 後面的表達式是正確的,那麼更改函式的傳回類型以允許它。

dart
Iterable<String> get zero sync* {
  yield '0';
}

永遠宣告傳回類型

#

函式 '{0}' 應該要有傳回類型,但沒有。

方法 '{0}' 應該要有傳回類型,但沒有。

描述

#

當方法或函式沒有明確的傳回類型時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函式 f 沒有傳回類型

dart
f() {}

常見修正方式

#

新增明確的傳回類型。

dart
void f() {}

永遠將控制主體放在新行

#

陳述式應該在不同的行上。

描述

#

當受控制流程陳述式 (`if`、`for`、`while` 或 `do`) 控制的程式碼與控制流程陳述式在同一行時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `return` 陳述式與控制 `return` 是否會執行的 `if` 在同一行。

dart
void f(bool b) {
  if (b) return;
}

常見修正方式

#

將受控制的陳述式放在不同的、縮排的行上。

dart
void f(bool b) {
  if (b)
    return;
}

永遠將必要的具名參數放在最前面

#

必要的具名參數應該在可選的具名參數之前。

描述

#

當必要的具名參數出現在可選的具名參數之後時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為必要的參數 x 在可選的參數 y 之後

dart
void f({int? y, required int x}) {}

常見修正方式

#

重新排序參數,使所有必要的具名參數都在任何可選的具名參數之前。

dart
void f({required int x, int? y}) {}

永遠使用套件匯入

#

對於 'lib' 目錄中的檔案,請使用 'package:' 匯入。

描述

#

當 `lib` 目錄內的程式庫中的 `import` 使用相對路徑來匯入同一套件的 `lib` 目錄內的另一個程式庫時,分析器會產生此診斷訊息。

範例

#

假設名為 `a.dart` 的檔案和以下程式碼都在同一套件的 `lib` 目錄內,以下程式碼會產生此診斷訊息,因為使用了相對 URI 來匯入 `a.dart`。

dart
import 'a.dart';

常見修正方式

#

使用套件匯入。

dart
import 'package:p/a.dart';

註解覆寫

#

成員 '{0}' 覆寫了繼承的成員,但未以 '@override' 註解。

描述

#

當成員覆寫了繼承的成員,但未以 `@override` 註解時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別 `B` 中的方法 `m` 覆寫了類別 `A` 中具有相同名稱的方法,但未標記為有意覆寫

dart
class A {
  void m() {}
}

class B extends A {
  void m() {}
}

常見修正方式

#

如果子類別中的成員旨在覆寫超類別中的成員,那麼新增 `@override` 註解。

dart
class A {
  void m() {}
}

class B extends A {
  @override
  void m() {}
}

如果子類別中的成員不旨在覆寫超類別中的成員,那麼重新命名其中一個成員。

dart
class A {
  void m() {}
}

class B extends A {
  void m2() {}
}

避免空的_else

#

空的陳述式在 'else' 子句中是不允許的。

描述

#

當 `else` 後面的陳述式是空的陳述式 (分號) 時,分析器會產生此診斷訊息。

如需更多資訊,請參閱 avoid_empty_else 的文件。

範例

#

以下程式碼會產生此診斷訊息,因為 `else` 後面的陳述式是空的陳述式

dart
void f(int x, int y) {
  if (x > y)
    print("1");
  else ;
    print("2");
}

常見修正方式

#

如果空陳述式之後的陳述式旨在僅在條件為 `false` 時執行,那麼移除空陳述式。

dart
void f(int x, int y) {
  if (x > y)
    print("1");
  else
    print("2");
}

如果沒有旨在僅在條件為 `false` 時執行的程式碼,那麼移除整個 `else` 子句。

dart
void f(int x, int y) {
  if (x > y)
    print("1");
  print("2");
}

避免在_forEach呼叫中使用函式字面值

#

函式字面量不應傳遞給 'forEach'。

描述

#

當 `Iterable.forEach` 的引數是閉包時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `forEach` 調用的引數是一個閉包

dart
void f(Iterable<String> s) {
  s.forEach((e) => print(e));
}

常見修正方式

#

如果閉包可以被 tear-off 取代,那麼取代閉包。

dart
void f(Iterable<String> s) {
  s.forEach(print);
}

如果閉包無法被 tear-off 取代,那麼使用 `for` 迴圈來迭代元素。

dart
void f(Iterable<String> s) {
  for (var e in s) {
    print(e);
  }
}

避免_FutureOr<void>

#

不要使用類型 'FutureOr'。'.

描述

#

當類型 FutureOr<void> 用作結果的類型時 (精確地說:它用在非變異位置),分析器會產生此診斷訊息。類型 FutureOr<void> 是有問題的,因為它可能看似編碼結果是 Future<void>,或者結果應該被捨棄 (當它是 void 時)。然而,沒有安全的方法可以偵測我們是屬於哪種情況,因為類型為 void 的表達式可以評估為任何物件,包括任何類型的 future。

具有類型含義類似於「忽略此物件;另外,請看一下,因為它可能是一個 future」在概念上也是不合理的。

對於類型 `FutureOr<void>` 的逆變情況 (例如,對於形式參數的類型) 進行了例外處理,並且對於這些情況不會發出警告。此例外的原因是該類型不描述結果,而是描述對其他人提供的值的約束。同樣地,對於類型別名宣告也進行了例外處理,因為它們很可能在逆變位置中使用 (例如,作為形式參數的類型)。因此,在類型別名宣告中,僅檢查類型參數邊界。

範例

#
dart
import 'dart:async';

FutureOr<void> m() => null;

常見修正方式

#

類型 `FutureOr<void>` 的一個替代方案 (通常很有用) 是 `Future<void>?`。此類型編碼結果是 `Future<void>` 或 null,並且在運行時沒有歧義,因為沒有物件可以同時具有這兩種類型。

可能並非總是可以使用類型 `Future<void>?` 作為類型 `FutureOr<void>` 的替代方案,因為後者是所有類型的超類型,而前者不是。在這種情況下,將 `FutureOr<void>` 替換為類型 `void` 可能是一種有用的補救措施。

避免初始化為_null

#

多餘地初始化為 'null'。

描述

#

當可為 null 的變數被明確初始化為 `null` 時,分析器會產生此診斷訊息。變數可以是區域變數、欄位或頂層變數。

未明確初始化的變數或欄位會自動初始化為 `null`。在 Dart 中沒有「未初始化的記憶體」的概念。

範例

#

以下程式碼會產生此診斷訊息,因為變數 `f` 被明確初始化為 `null`

dart
class C {
  int? f = null;

  void m() {
    if (f != null) {
      print(f);
    }
  }
}

常見修正方式

#

移除不必要的初始化。

dart
class C {
  int? f;

  void m() {
    if (f != null) {
      print(f);
    }
  }
}

避免_print

#

不要在生產程式碼中調用 'print'。

描述

#

當在生產程式碼中調用函式 `print` 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函式 `print` 無法在生產環境中調用。

dart
void f(int x) {
  print('x = $x');
}

常見修正方式

#

如果您正在編寫使用 Flutter 的程式碼,那麼請使用函式 debugPrint,並使用 kDebugMode 進行測試保護。

dart
import 'package:flutter/foundation.dart';

void f(int x) {
  if (kDebugMode) {
    debugPrint('x = $x');
  }
}

如果您正在編寫不使用 Flutter 的程式碼,那麼請使用記錄服務 (例如 package:logging) 來寫入資訊。

避免相對_lib匯入

#

不能使用相對路徑匯入 'lib' 中的程式庫。

描述

#

當 `import` 指令中的 URI 在路徑中包含 `lib` 時,分析器會產生此診斷訊息。

範例

#

假設 `lib` 目錄中有名為 `a.dart` 的檔案

dart
class A {}

以下程式碼會產生此診斷訊息,因為匯入包含一個包含 `lib` 的路徑

dart
import '../lib/a.dart';

常見修正方式

#

重寫匯入以不在 URI 中包含 `lib`。

dart
import 'a.dart';

避免重新命名方法參數

#

參數名稱 '{0}' 與覆寫方法中的名稱 '{1}' 不符。

描述

#

當從超類別覆寫方法的方法更改參數名稱時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `B` 中方法 `m` 的參數名為 `b`,這與 `A` 中覆寫方法的參數名稱不同

dart
class A {
  void m(int a) {}
}

class B extends A {
  @override
  void m(int b) {}
}

常見修正方式

#

重新命名其中一個參數,使它們相同。

dart
class A {
  void m(int a) {}
}

class B extends A {
  @override
  void m(int a) {}
}

避免_setter的傳回類型

#

setter 上不必要的傳回類型。

描述

#

當 setter 具有明確的傳回類型時,分析器會產生此診斷訊息。

Setter 永遠不會傳回值,因此宣告 setter 的傳回類型是多餘的。

範例

#

以下程式碼會產生此診斷訊息,因為 setter `s` 具有明確的傳回類型 (`void`)

dart
void set s(int p) {}

常見修正方式

#

移除傳回類型。

dart
set s(int p) {}

避免為_void傳回_null

#

不要從傳回類型為 'void' 的函式傳回 'null'。

不要從傳回類型為 'void' 的方法傳回 'null'。

描述

#

當傳回類型為 `void` 的函式明確傳回 `null` 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為在 `void` 函式中有明確的 `null` 傳回

dart
void f() {
  return null;
}

常見修正方式

#

移除不必要的明確 `null`。

dart
void f() {
  return;
}

避免遮蔽類型參數

#

類型參數 '{0}' 遮蔽了封閉 {1} 的類型參數。

描述

#

當類型參數遮蔽了封閉宣告的類型參數時,分析器會產生此診斷訊息。

使用不同的類型參數遮蔽類型參數可能會導致難以偵錯的細微錯誤。

範例

#

以下程式碼會產生此診斷訊息,因為方法 `m` 定義的類型參數 `T` 遮蔽了類別 `C` 定義的類型參數 `T`

dart
class C<T> {
  void m<T>() {}
}

常見修正方式

#

重新命名其中一個類型參數。

dart
class C<T> {
  void m<S>() {}
}

避免在運算式陳述式中使用單一串聯

#

不必要的串聯表達式。

描述

#

當使用單一串聯運算子且表達式的值未用於任何用途 (例如賦值給變數或作為引數傳遞) 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為串聯表達式 `s..length` 的值未被使用

dart
void f(String s) {
  s..length;
}

常見修正方式

#

將串聯運算子替換為簡單的存取運算子。

dart
void f(String s) {
  s.length;
}

避免緩慢的_async_IO

#

使用非同步 'dart:io' 方法。

描述

#

當使用具有同步等效項的非同步檔案 I/O 方法時,分析器會產生此診斷訊息。

以下是標記的特定非同步方法

  • Directory.exists
  • Directory.stat
  • File.lastModified
  • File.exists
  • File.stat
  • FileSystemEntity.isDirectory
  • FileSystemEntity.isFile
  • FileSystemEntity.isLink
  • FileSystemEntity.type

範例

#

以下程式碼會產生此診斷訊息,因為調用了非同步方法 `exists`

dart
import 'dart:io';

Future<void> g(File f) async {
  await f.exists();
}

常見修正方式

#

使用方法的同步版本。

dart
import 'dart:io';

void g(File f) {
  f.existsSync();
}

避免類型轉字串

#

在生產程式碼中對 'Type' 使用 'toString' 是不安全的。

描述

#

當在靜態類型為 `Type` 的值上調用方法 `toString` 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為方法 `toString` 在 `runtimeType` 傳回的 `Type` 上調用

dart
bool isC(Object o) => o.runtimeType.toString() == 'C';

class C {}

常見修正方式

#

如果類型必須完全相同,那麼使用明確的比較。

dart
bool isC(Object o) => o.runtimeType == C;

class C {}

如果類型的子類型的實例傳回 `true` 是可以接受的,那麼使用類型檢查。

dart
bool isC(Object o) => o is C;

class C {}

避免類型作為參數名稱

#

參數名稱 '{0}' 與可見類型名稱相符。

描述

#

當參數列表中的參數名稱與可見類型 (名稱在作用域內的類型) 相同時,分析器會產生此診斷訊息。

這通常表示預期的參數名稱遺失,導致使用類型名稱作為參數名稱而不是參數的類型。即使情況並非如此 (參數名稱是有意的),參數名稱也會遮蔽現有類型,這可能會導致難以診斷的錯誤。

範例

#

以下程式碼會產生此診斷訊息,因為函式 `f` 有一個名為 `int` 的參數,它遮蔽了 `dart:core` 中的類型 `int`

dart
void f(int) {}

常見修正方式

#

如果缺少參數名稱,那麼為參數新增名稱。

dart
void f(int x) {}

如果參數旨在具有 `dynamic` 的隱式類型,那麼重新命名參數,使其不會遮蔽任何可見類型的名稱。

dart
void f(int_) {}

避免不必要的容器

#

'Container' 的不必要實例。

描述

#

當 widget 樹包含 `Container` 的實例且建構子的唯一引數是 `child:` 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `Container` 建構子的調用僅具有 `child:` 引數

dart
import 'package:flutter/material.dart';

Widget buildRow() {
  return Container(
    child: Row(
      children: [
        Text('a'),
        Text('b'),
      ],
    )
  );
}

常見修正方式

#

如果您打算為建構子提供其他引數,那麼新增它們。

dart
import 'package:flutter/material.dart';

Widget buildRow() {
  return Container(
    color: Colors.red.shade100,
    child: Row(
      children: [
        Text('a'),
        Text('b'),
      ],
    )
  );
}

如果不需要其他引數,那麼解包子 widget。

dart
import 'package:flutter/material.dart';

Widget buildRow() {
  return Row(
    children: [
      Text('a'),
      Text('b'),
    ],
  );
}

避免在_Flutter中使用網頁程式庫

#

不要在 Flutter web 外掛程式之外使用僅限 web 的程式庫。

描述

#

當不是 web 外掛程式的套件中的程式庫包含僅限 web 的程式庫的匯入時,分析器會產生此診斷訊息。

  • dart:html
  • dart:js
  • dart:js_util
  • dart:js_interop
  • dart:js_interop_unsafe
  • package:js
  • package:web

範例

#

當在不是 web 外掛程式的套件中找到時,以下程式碼會產生此診斷訊息,因為它匯入了 `dart:html`

dart
import 'dart:html';

import 'package:flutter/material.dart';

class C {}

常見修正方式

#

如果套件不打算成為 web 外掛程式,那麼移除匯入。

dart
import 'package:flutter/material.dart';

class C {}

如果套件打算成為 web 外掛程式,那麼將以下幾行新增到套件的 `pubspec.yaml` 檔案中。

yaml
flutter:
  plugin:
    platforms:
      web:
        pluginClass: HelloPlugin
        fileName: hello_web.dart

如需更多資訊,請參閱 開發套件和外掛程式

僅等待_Future

#

在 '{0}' 的實例上使用 'await',它不是 'Future' 的子類型。

描述

#

當 `await` 後面的表達式具有 `Future<T>`、`FutureOr<T>`、`Future<T>?`、`FutureOr<T>?` 或 `dynamic` 以外的任何類型時,分析器會產生此診斷訊息。

對於表達式 `await null` 進行了例外處理,因為它是引入微任務延遲的常用方法。

除非表達式可以產生 `Future`,否則 `await` 是不必要的,並且可能導致讀者假設不存在的非同步級別。

範例

#

以下程式碼會產生此診斷訊息,因為 `await` 後面的表達式具有 `int` 類型

dart
void f() async {
  await 23;
}

常見修正方式

#

移除 `await`。

dart
void f() async {
  23;
}

駝峰式命名擴充功能

#

擴充功能名稱 '{0}' 不是 UpperCamelCase 識別符。

描述

#

當擴充功能的名稱未使用 'UpperCamelCase' 命名慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為擴充功能的名稱不是以大寫字母開頭

dart
extension stringExtension on String {}

常見修正方式

#

如果擴充功能需要有名稱 (需要在此外程式庫之外可見),那麼重新命名擴充功能,使其具有有效的名稱。

dart
extension StringExtension on String {}

如果擴充功能不需要有名稱,那麼移除擴充功能的名稱。

dart
extension on String {}

駝峰式命名類型

#

類型名稱 '{0}' 不是 UpperCamelCase 識別符。

描述

#

當類型 (類別、mixin、列舉或 typedef) 的名稱未使用 'UpperCamelCase' 命名慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為類別的名稱不是以大寫字母開頭

dart
class c {}

常見修正方式

#

重新命名類型,使其具有有效的名稱。

dart
class C {}

取消訂閱

#

'StreamSubscription' 的未取消實例。

描述

#

當建立 `StreamSubscription` 的實例但未調用方法 `cancel` 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `subscription` 未被取消

dart
import 'dart:async';

void f(Stream stream) {
  // ignore: unused_local_variable
  var subscription = stream.listen((_) {});
}

常見修正方式

#

取消 subscription。

dart
import 'dart:async';

void f(Stream stream) {
  var subscription = stream.listen((_) {});
  subscription.cancel();
}

關閉接收器

#

'Sink' 的未關閉實例。

描述

#

當建立 `Sink` 的實例但未調用方法 `close` 時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `sink` 未被關閉

dart
import 'dart:io';

void g(File f) {
  var sink = f.openWrite();
  sink.write('x');
}

常見修正方式

#

關閉 sink。

dart
import 'dart:io';

void g(File f) {
  var sink = f.openWrite();
  sink.write('x');
  sink.close();
}

集合方法不相關的類型

#

引數類型 '{0}' 與 '{1}' 無關。

描述

#

當核心程式庫中的任何方法以不適當類型的引數調用時,分析器會產生此診斷訊息。這些方法是不為參數提供足夠特定類型的方法,以允許常規類型檢查捕獲錯誤。

檢查的引數是

  • Iterable<E>.contains 的引數應與 E 相關
  • List<E>.remove 的引數應與 E 相關
  • Map<K, V>.containsKey 的引數應與 K 相關
  • Map<K, V>.containsValue 的引數應與 V 相關
  • Map<K, V>.remove 的引數應與 K 相關
  • Map<K, V>.[] 的引數應與 K 相關
  • Queue<E>.remove 的引數應與 E 相關
  • Set<E>.lookup 的引數應與 E 相關
  • Set<E>.remove 的引數應與 E 相關

範例

#

以下程式碼會產生此診斷訊息,因為 `contains` 的引數是一個 `String`,它無法賦值給 `int`,列表 `l` 的元素類型

dart
bool f(List<int> l)  => l.contains('1');

常見修正方式

#

如果元素類型是正確的,那麼更改引數以具有相同的類型。

dart
bool f(List<int> l)  => l.contains(1);

如果引數類型是正確的,那麼更改元素類型。

dart
bool f(List<String> l)  => l.contains('1');

常數識別項名稱

#

常數名稱 '{0}' 不是 lowerCamelCase 識別符。

描述

#

當常數的名稱不遵循 lowerCamelCase 命名慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為頂層變數的名稱不是 lowerCamelCase 識別符

dart
const EMPTY_STRING = '';

常見修正方式

#

重寫名稱以遵循 lowerCamelCase 命名慣例。

dart
const emptyString = '';

finally中的控制流程

#

在 'finally' 子句中使用 '{0}'。

描述

#

當 `finally` 子句包含 `return`、`break` 或 `continue` 陳述式時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為在 `finally` 區塊內有一個 `return` 陳述式

dart
int f() {
  try {
    return 1;
  } catch (e) {
    print(e);
  } finally {
    return 0;
  }
}

常見修正方式

#

如果不需要該陳述式,那麼移除該陳述式,如果區塊為空,則移除 `finally` 子句。

dart
int f() {
  try {
    return 1;
  } catch (e) {
    print(e);
  }
}

如果需要該陳述式,那麼將該陳述式移動到 `finally` 區塊之外。

dart
int f() {
  try {
    return 1;
  } catch (e) {
    print(e);
  }
  return 0;
}

流程控制結構中的大括號

#

{0} 中的陳述式應該用區塊括起來。

描述

#

當控制結構 (`if`、`for`、`while` 或 `do` 陳述式) 具有區塊以外的陳述式時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 `then` 陳述式未用區塊括起來

dart
int f(bool b) {
  if (b)
    return 1;
  return 0;
}

常見修正方式

#

在應該是區塊的陳述式周圍新增大括號。

dart
int f(bool b) {
  if (b) {
    return 1;
  }
  return 0;
}

懸掛的程式庫文件註解

#

懸空的程式庫文件註解。

描述

#

當看似是程式庫文件的文件註解後面沒有 `library` 指令時,分析器會產生此診斷訊息。更具體地說,當文件註解出現在程式庫中的第一個指令之前 (假設它不是 `library` 指令),或在第一個頂層宣告之前,並且與該宣告之間隔著一個或多個空行時,就會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為在第一個 `import` 指令之前有一個文件註解

dart
/// This is a great library.
import 'dart:core';

以下程式碼會產生此診斷訊息,因為在第一個類別宣告之前有一個文件註解,但註解和宣告之間有一個空行。

dart
/// This is a great library.

class C {}

常見修正方式

#

如果註解是程式庫文件,那麼新增一個沒有名稱的 `library` 指令。

dart
/// This is a great library.
library;

import 'dart:core';

如果註解是以下宣告的文件,那麼移除空行。

dart
/// This is a great library.
class C {}

依賴參考的套件

#

匯入的套件 '{0}' 不是匯入套件的依賴項。

描述

#

當套件匯入參照到未在 pubspec.yaml 檔案中指定的套件時,分析器會產生此診斷訊息。

明確地依賴您參考的套件可確保它們始終存在,並允許您對它們設定依賴項約束,以防止重大變更。

範例

#

給定一個包含以下內容的 pubspec.yaml 檔案

yaml
dependencies:
  meta: ^3.0.0

以下程式碼會產生此診斷訊息,因為沒有對套件 a 的依賴項

dart
import 'package:a/a.dart';

常見修正方式

#

依賴項應該是常規依賴項還是開發依賴項,取決於套件是從公共函式庫(libbin 下的函式庫)還是僅從私有函式庫(例如 test 下的函式庫)引用。

如果套件至少從一個公共函式庫引用,則在 pubspec.yaml 檔案的 dependencies 欄位下新增對該套件的常規依賴項

yaml
dependencies:
  a: ^1.0.0
  meta: ^3.0.0

如果套件僅從私有函式庫引用,則在 pubspec.yaml 檔案的 dev_dependencies 欄位下新增對該套件的開發依賴項

yaml
dependencies:
  meta: ^3.0.0
dev_dependencies:
  a: ^1.0.0

空的_catch區塊

#

空的 catch 區塊。

描述

#

catch 子句中的區塊為空時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 catch 區塊為空

dart
void f() {
  try {
    print('Hello');
  } catch (exception) {}
}

常見修正方式

#

如果例外狀況不應被忽略,則新增程式碼來處理例外狀況

dart
void f() {
  try {
    print('We can print.');
  } catch (exception) {
    print("We can't print.");
  }
}

如果例外狀況旨在被忽略,則新增註解說明原因

dart
void f() {
  try {
    print('We can print.');
  } catch (exception) {
    // Nothing to do.
  }
}

如果例外狀況旨在被忽略,並且沒有充分的理由解釋原因,則重新命名例外狀況參數

dart
void f() {
  try {
    print('We can print.');
  } catch (_) {}
}

空的建構子主體

#

空的建構子主體應使用 ';' 而不是 '{}' 撰寫。

描述

#

當建構子具有空的區塊主體時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 C 的建構子具有空的區塊主體

dart
class C {
  C() {}
}

常見修正方式

#

將區塊替換為分號

dart
class C {
  C();
}

空的陳述式

#

不必要的空陳述式。

描述

#

當找到空陳述式時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為由 while 迴圈控制的陳述式是空陳述式

dart
void f(bool condition) {
  while (condition);
    g();
}

void g() {}

常見修正方式

#

如果沒有需要控制的陳述式,則移除空陳述式及其所屬的控制結構(請注意,移除的任何其他程式碼是否具有需要保留的副作用)

dart
void f(bool condition) {
  g();
}

void g() {}

如果沒有需要控制的陳述式,但由於其他原因仍然需要控制結構,則將空陳述式替換為區塊,以使程式碼的結構更清晰

dart
void f(bool condition) {
  while (condition) {}
  g();
}

void g() {}

如果有需要控制的陳述式,則移除空陳述式並調整程式碼,使適當的陳述式受到控制,可能需要新增區塊

dart
void f(bool condition) {
  while (condition) {
    g();
  }
}

void g() {}

檔案名稱

#

檔案名稱 '{0}' 不是 lower_case_with_underscores 識別符。

描述

#

.dart 檔案的名稱未使用 lower_case_with_underscores 時,分析器會產生此診斷訊息。

範例

#

名為 SliderMenu.dart 的檔案會產生此診斷訊息,因為檔案名稱使用了 UpperCamelCase 慣例。

常見修正方式

#

重新命名檔案以使用 lower_case_with_underscores 慣例,例如 slider_menu.dart

hash和_equals

#

缺少 '{0}' 的對應覆寫。

描述

#

當類別或 mixin 覆寫了 == 的定義但未覆寫 hashCode 的定義,反之亦然,覆寫了 hashCode 的定義但未覆寫 == 的定義時,分析器會產生此診斷訊息。

對於常見的雜湊表實作能夠正常運作,物件的 == 運算子和 hashCode 屬性都必須保持一致。因此,當覆寫任一方法時,兩者都應被覆寫。

範例

#

以下程式碼會產生此診斷訊息,因為類別 C 覆寫了 == 運算子,但未覆寫 getter hashCode

dart
class C {
  final int value;

  C(this.value);

  @override
  bool operator ==(Object other) =>
      other is C &&
      other.runtimeType == runtimeType &&
      other.value == value;
}

常見修正方式

#

如果您需要覆寫其中一個成員,則新增另一個成員的覆寫

dart
class C {
  final int value;

  C(this.value);

  @override
  bool operator ==(Object other) =>
      other is C &&
      other.runtimeType == runtimeType &&
      other.value == value;

  @override
  int get hashCode => value.hashCode;
}

如果您不需要覆寫任何一個成員,則移除不必要的覆寫

dart
class C {
  final int value;

  C(this.value);
}

實作匯入

#

從另一個套件的 'lib/src' 目錄匯入函式庫。

描述

#

當匯入參照到不同套件的 lib/src 目錄內的函式庫時,分析器會產生此診斷訊息,這違反了 pub 套件的慣例

範例

#

以下程式碼,假設它不是 ffi 套件的一部分,會產生此診斷訊息,因為被匯入的函式庫位於頂層 src 目錄內

dart
import 'package:ffi/src/allocation.dart';

常見修正方式

#

如果被匯入的函式庫包含屬於公共 API 的程式碼,則匯入匯出公共 API 的公共函式庫

dart
import 'package:ffi/ffi.dart';

如果被匯入的函式庫不是套件公共 API 的一部分,則尋找其他方法來達成您的目標(假設可能),或開啟 issue 要求套件作者將其納入公共 API。

隱含呼叫拆解

#

方法 'call' 的隱式 tear-off。

描述

#

當具有 call 方法的物件被賦值給函式類型變數時,分析器會產生此診斷訊息,隱式地 tear off call 方法。

範例

#

以下程式碼會產生此診斷訊息,因為 Callable 的實例被傳遞給期望 Function 的函式

dart
class Callable {
  void call() {}
}

void callIt(void Function() f) {
  f();
}

void f() {
  callIt(Callable());
}

常見修正方式

#

顯式地 tear off call 方法

dart
class Callable {
  void call() {}
}

void callIt(void Function() f) {
  f();
}

void f() {
  callIt(Callable().call);
}

使用_JS互通類型進行無效的執行階段檢查

#

從 '{0}' 到 '{1}' 的轉換會將 Dart 值轉換為 JS 互通類型,這可能不具有跨平台一致性。

從 '{0}' 到 '{1}' 的轉換會將 JS 互通值轉換為 Dart 類型,這可能不具有跨平台一致性。

從 '{0}' 到 '{1}' 的轉換會將 JS 互通值轉換為不相容的 JS 互通類型,這可能不具有跨平台一致性。

'{0}' 和 '{1}' 之間的執行階段檢查會檢查 Dart 值是否為 JS 互通類型,這可能不具有跨平台一致性。

'{0}' 和 '{1}' 之間的執行階段檢查會檢查 JS 互通值是否為 Dart 類型,這可能不具有跨平台一致性。

'{0}' 和 '{1}' 之間的執行階段檢查涉及兩個 JS 互通類型之間可能不具有跨平台一致性的非簡單執行階段檢查。

'{0}' 和 '{1}' 之間的執行階段檢查涉及 JS 互通值和不相關的 JS 互通類型之間的執行階段檢查,這將始終為 true,並且不會檢查底層類型。

描述

#

is 測試具有以下情況時,分析器會產生此診斷訊息:

  • 右手邊是 JS 互通類型,無論是直接的還是作為另一個類型的類型參數,或
  • 左手邊是 JS 互通值。

範例

#

以下程式碼會產生此診斷訊息,因為 JS 互通類型 JSBooleanis 測試的右手邊

dart
import 'dart:js_interop';

bool f(Object b) => b is JSBoolean;

以下程式碼會產生此診斷訊息,因為 JS 互通類型 JSString 用作 is 測試右手邊的類型參數

dart
import 'dart:js_interop';

bool f(List<Object> l) => l is List<JSString>;

以下程式碼會產生此診斷訊息,因為 JS 互通值 ais 測試的左手邊

dart
import 'dart:js_interop';

bool f(JSAny a) => a is String;

常見修正方式

#

使用 JS 互通輔助程式,例如 isA,來檢查 JS 互通值的底層類型

dart
import 'dart:js_interop';

void f(Object b) => b.jsify()?.isA<JSBoolean>();

無效地使用請勿提交的成員

#

'{0}' 的使用不應提交到原始碼控制。

描述

#

當使用 @doNotSubmit 註解的成員在也使用 @doNotSubmit 註解的成員宣告之外被參照時,分析器會產生此診斷訊息。

範例

#

假設一個檔案 a.dart 包含以下宣告

dart
import 'package:meta/meta.dart';

@doNotSubmit
void emulateCrash() { /* ... */ }

以下程式碼會產生此診斷訊息,因為宣告在也使用 @doNotSubmit 註解的成員之外被參照

dart
import 'a.dart';

void f() {
  emulateCrash();
}

常見修正方式

#

最常見的情況是,在完成本機測試後,應移除對成員的參照。

如果在成員之上建構額外功能,也請使用 @doNotSubmit 註解新新增的成員

dart
import 'package:meta/meta.dart';

import 'a.dart';

@doNotSubmit
void emulateCrashWithOtherFunctionality() {
  emulateCrash();
  // do other things.
}

程式庫註解

#

此註解應附加到函式庫指令。

描述

#

當適用於整個函式庫的註解未與 library 指令關聯時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 TestOn 註解(適用於整個函式庫)與 import 指令而不是 library 指令關聯

dart
@TestOn('browser')

import 'package:test/test.dart';

void main() {}

常見修正方式

#

將註解與 library 指令關聯,必要時新增一個

dart
@TestOn('browser')
library;

import 'package:test/test.dart';

void main() {}

程式庫名稱

#

函式庫名稱 '{0}' 不是 lower_case_with_underscores 識別符。

描述

#

當函式庫的名稱未使用 lower_case_with_underscores 命名慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為函式庫名稱 libraryName 不是 lower_case_with_underscores 識別符

dart
library libraryName;

常見修正方式

#

如果不需要函式庫名稱,則移除函式庫名稱

dart
library;

如果需要函式庫名稱,則將其轉換為使用 lower_case_with_underscores 命名慣例

dart
library library_name;

程式庫前置詞

#

前綴 '{0}' 不是 lower_case_with_underscores 識別符。

描述

#

當匯入前綴未使用 lower_case_with_underscores 命名慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為前綴 ffiSupport 不是 lower_case_with_underscores 識別符

dart
import 'package:ffi/ffi.dart' as ffiSupport;

常見修正方式

#

轉換前綴以使用 lower_case_with_underscores 命名慣例

dart
import 'package:ffi/ffi.dart' as ffi_support;

公用_API中的程式庫私有類型

#

在公共 API 中無效地使用私有類型。

描述

#

當函式庫公共 API 中參照了不屬於該函式庫公共 API 的類型時,分析器會產生此診斷訊息。

在公共 API 中使用私有類型可能會使 API 在定義函式庫之外無法使用。

範例

#

以下程式碼會產生此診斷訊息,因為公共函式 f 的參數 c 具有函式庫私有類型 (_C)

dart
void f(_C c) {}

class _C {}

常見修正方式

#

如果 API 不需要於定義函式庫之外使用,則將其設為私有

dart
void _f(_C c) {}

class _C {}

如果 API 需要成為函式庫公共 API 的一部分,則使用不同的公共類型,或將被參照的類型設為公共

dart
void f(C c) {}

class C {}

僅限字面值的布林運算式

#

布林運算式具有常數值。

描述

#

if 或迴圈陳述式中條件的值已知始終為 true 或始終為 false 時,分析器會產生此診斷訊息。 while 迴圈的條件為布林文字 true 時除外。

範例

#

以下程式碼會產生此診斷訊息,因為條件將始終評估為 true

dart
void f() {
  if (true) {
    print('true');
  }
}

lint 將評估由常數組成的運算式子集,因此以下程式碼也會產生此診斷訊息,因為條件將始終評估為 false

dart
void g(int i) {
  if (1 == 0 || 3 > 4) {
    print('false');
  }
}

常見修正方式

#

如果條件錯誤,則更正條件,使其值在編譯時無法得知

dart
void g(int i) {
  if (i == 0 || i > 4) {
    print('false');
  }
}

如果條件正確,則簡化程式碼以不評估條件

dart
void f() {
  print('true');
}

清單中沒有相鄰字串

#

請勿在列表文字中使用相鄰的字串。

描述

#

當兩個字串文字在列表文字中相鄰時,分析器會產生此診斷訊息。 Dart 中相鄰的字串會串連在一起形成單個字串,但意圖可能是每個字串都是列表中的單獨元素。

範例

#

以下程式碼會產生此診斷訊息,因為字串 'a''b' 相鄰

dart
List<String> list = ['a' 'b', 'c'];

常見修正方式

#

如果兩個字串旨在成為列表的單獨元素,則在它們之間新增逗號

dart
List<String> list = ['a', 'b', 'c'];

如果兩個字串旨在成為單個串連的字串,則手動合併字串

dart
List<String> list = ['ab', 'c'];

或使用 + 運算子來串連字串

dart
List<String> list = ['a' + 'b', 'c'];

沒有重複的_case值

#

case 子句的值 ('{0}') 等於較早的 case 子句的值 ('{1}')。

描述

#

當同一個 switch 陳述式中的兩個或多個 case 子句具有相同的值時,分析器會產生此診斷訊息。

第一個之後的任何 case 子句都無法執行,因此具有重複的 case 子句會產生誤導。

此診斷訊息通常是由於錯字或常數值的變更所導致。

範例

#

以下程式碼會產生此診斷訊息,因為兩個 case 子句具有相同的值 (1)

dart
// @dart = 2.14
void f(int v) {
  switch (v) {
    case 1:
      break;
    case 1:
      break;
  }
}

常見修正方式

#

如果其中一個子句應具有不同的值,則變更子句的值

dart
void f(int v) {
  switch (v) {
    case 1:
      break;
    case 2:
      break;
  }
}

如果值正確,則將陳述式合併到單個子句中

dart
void f(int v) {
  switch (v) {
    case 1:
      break;
  }
}

程式庫前置詞沒有前導底線

#

函式庫前綴 '{0}' 以底線開頭。

描述

#

當在匯入上宣告的前綴名稱以底線開頭時,分析器會產生此診斷訊息。

函式庫前綴本質上在宣告函式庫之外不可見,因此指示私有的前導底線沒有增加任何價值。

範例

#

以下程式碼會產生此診斷訊息,因為前綴 _core 以底線開頭

dart
import 'dart:core' as _core;

常見修正方式

#

移除底線

dart
import 'dart:core' as core;

本機識別項沒有前導底線

#

區域變數 '{0}' 以底線開頭。

描述

#

當區域變數的名稱以底線開頭時,分析器會產生此診斷訊息。

區域變數本質上在宣告函式庫之外不可見,因此指示私有的前導底線沒有增加任何價值。

範例

#

以下程式碼會產生此診斷訊息,因為參數 _s 以底線開頭

dart
int f(String _s) => _s.length;

常見修正方式

#

移除底線

dart
int f(String s) => s.length;

createState中沒有邏輯

#

請勿在 'createState' 中放置任何邏輯。

描述

#

StatefulWidget 子類別中的 createState 實作包含除傳回調用零參數建構子的結果之外的任何邏輯時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為建構子調用具有參數

dart
import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  @override
  MyState createState() => MyState(0);
}

class MyState extends State {
  int x;

  MyState(this.x);
}

常見修正方式

#

重寫程式碼,使 createState 不包含任何邏輯

dart
import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  @override
  MyState createState() => MyState();
}

class MyState extends State {
  int x = 0;

  MyState();
}

沒有萬用字元變數使用

#

被參照的識別符是萬用字元。

描述

#

當參照名稱僅由底線組成的參數或區域變數時,分析器會產生此診斷訊息。 此類名稱在未來版本的 Dart 語言中將變為非綁定,從而使參照變為非法。

範例

#

以下程式碼會產生此診斷訊息,因為參數的名稱由兩個底線組成

dart
// @dart = 3.6
void f(int __) {
  print(__);
}

以下程式碼會產生此診斷訊息,因為區域變數的名稱由單個底線組成

dart
// @dart = 3.6
void f() {
  int _ = 0;
  print(_);
}

常見修正方式

#

如果變數或參數旨在被參照,則給它一個至少有一個非底線字元的名稱

dart
void f(int p) {
  print(p);
}

如果變數或參數不旨在被參照,則將參照替換為不同的運算式

dart
void f() {
  print(0);
}

非常數識別項名稱

#

變數名稱 '{0}' 不是 lowerCamelCase 識別符。

描述

#

當類別成員、頂層宣告、變數、參數、具名參數或未宣告為 const 的具名建構子的名稱未使用 lowerCamelCase 慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為頂層變數 Count 不是以小寫字母開頭

dart
var Count = 0;

常見修正方式

#

變更宣告中的名稱以遵循 lowerCamelCase 慣例

dart
var count = 0;

可為 Null 類型參數的空值檢查

#

空值檢查運算子不應在類型為可能為可空類型參數的變數上使用。

描述

#

當在類型為 T? 的變數上使用空值檢查運算子時,分析器會產生此診斷訊息,其中 T 是允許類型引數為可空的類型參數(沒有邊界或具有可空邊界)。

給定一個具有可空邊界的泛型類型參數 T,當使用 T? 類型的變數時,很容易引入錯誤的空值檢查。 具體來說,常見的情況是 T? x; 並希望斷言 x 已設定為類型 T 的有效值。 一個常見的錯誤是使用 x! 這樣做。 這幾乎總是錯誤的,因為如果 T 是可空類型,則 x 可能合法地將 null 作為類型 T 的值。

範例

#

以下程式碼會產生此診斷訊息,因為 t 的類型為 T?,並且 T 允許類型引數為可空(因為它沒有 extends 子句)

dart
T f<T>(T? t) => t!;

常見修正方式

#

使用類型參數來轉換變數

dart
T f<T>(T? t) => t as T;

覆寫的欄位

#

欄位覆寫從 '{0}' 繼承的欄位。

描述

#

當類別定義一個欄位,該欄位覆寫了來自超類別的欄位時,分析器會產生此診斷訊息。

用另一個欄位覆寫欄位會導致物件具有兩個不同的欄位,但由於這些欄位具有相同的名稱,因此在給定範圍內只能參照其中一個欄位。 這可能會導致混淆,即對其中一個欄位的參照可能會被誤認為是對另一個欄位的參照。

範例

#

以下程式碼會產生此診斷訊息,因為 B 中的欄位 f 遮蔽了 A 中的欄位 f

dart
class A {
  int f = 1;
}

class B extends A {
  @override
  int f = 2;
}

常見修正方式

#

如果兩個欄位表示相同的屬性,則從子類別中移除該欄位

dart
class A {
  int f = 1;
}

class B extends A {}

如果兩個欄位應該是不同的,則重新命名其中一個欄位

dart
class A {
  int f = 1;
}

class B extends A {
  int g = 2;
}

如果兩個欄位在某種程度上相關,但不能相同,則尋找不同的方法來實作您需要的語意。

套件名稱

#

套件名稱 '{0}' 不是 lower_case_with_underscores 識別符。

描述

#

當套件的名稱未使用 lower_case_with_underscores 命名慣例時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為套件的名稱使用了 lowerCamelCase 命名慣例

yaml
name: somePackage

常見修正方式

#

使用 lower_case_with_underscores 命名慣例重寫套件的名稱

yaml
name: some_package

套件前置詞程式庫名稱

#

函式庫名稱不是以套件名稱為前綴的點分隔路徑。

描述

#

當函式庫的名稱不遵循這些指南時,分析器會產生此診斷訊息

  • 所有函式庫名稱都以套件名稱為前綴。
  • 使入口函式庫具有與套件相同的名稱。
  • 對於套件中的所有其他函式庫,在套件名稱後新增函式庫 Dart 檔案的點分隔路徑。
  • 對於 lib 下的函式庫,省略頂層目錄名稱。

例如,給定一個名為 my_package 的套件,以下是套件中各種檔案的函式庫名稱

範例

#

假設包含以下程式碼的檔案不在名為 special.dart 的檔案中,而該檔案位於名為 something 的套件的 lib 目錄中(這將是規則的例外),分析器會產生此診斷訊息,因為函式庫的名稱不符合上述指南

dart
library something.special;

常見修正方式

#

變更函式庫的名稱以符合指南。

偏好相鄰字串串連

#

字串文字不應通過 '+' 運算子串連。

描述

#

當使用 + 運算子串連兩個字串文字時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為兩個字串文字正在使用 + 運算子串連

dart
var s = 'a' + 'b';

常見修正方式

#

移除運算子

dart
var s = 'a' 'b';

偏好集合字面值

#

不必要的建構子調用。

描述

#

當使用建構子建立列表、映射或集合,但文字會產生相同的結果時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 Map 的建構子正在被用來建立可以使用文字建立的映射

dart
var m = Map<String, String>();

常見修正方式

#

使用文字表示法

dart
var m = <String, String>{};

偏好條件賦值

#

'if' 陳述式可以替換為空值感知賦值。

描述

#

當變數的賦值取決於變數是否具有值 null,並且可以使用 ??= 運算子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為參數 s 正在與 null 進行比較,以確定是否賦值不同的值

dart
int f(String? s) {
  if (s == null) {
    s = '';
  }
  return s.length;
}

常見修正方式

#

使用 ??= 運算子而不是顯式的 if 陳述式

dart
int f(String? s) {
  s ??= '';
  return s.length;
}

偏好_const_建構子

#

將 'const' 與建構子一起使用以提高效能。

描述

#

當 const 建構子的調用既沒有以 const 為前綴,也沒有在 常數上下文 中時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 const 建構子的調用既沒有以 const 為前綴,也沒有在 常數上下文

dart
class C {
  const C();
}

C c = C();

常見修正方式

#

如果上下文可以設為 常數上下文,則執行此操作

dart
class C {
  const C();
}

const C c = C();

如果上下文無法設為 常數上下文,則在建構子調用之前新增 const

dart
class C {
  const C();
}

C c = const C();

偏好不可變物件中的_const_建構子

#

'@immutable' 類別中的建構子應宣告為 'const'。

描述

#

當在具有 @immutable 註解的類別中找到非 const 建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 C 中的建構子未宣告為 const,即使 C 具有 @immutable 註解

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final f;

  C(this.f);
}

常見修正方式

#

如果類別確實旨在是不可變的,則將 const 修飾符新增到建構子

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final f;

  const C(this.f);
}

如果類別是可變的,則移除 @immutable 註解

dart
class C {
  final f;

  C(this.f);
}

偏好_const_宣告

#

將 'const' 用於初始化為常數值的 final 變數。

描述

#

當頂層變數、靜態欄位或區域變數被標記為 final 並且初始化為常數值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為頂層變數 v 既是 final 又初始化為常數值

dart
final v = const <int>[];

以下程式碼會產生此診斷訊息,因為靜態欄位 f 既是 final 又初始化為常數值

dart
class C {
  static final f = const <int>[];
}

以下程式碼會產生此診斷訊息,因為區域變數 v 既是 final 又初始化為常數值

dart
void f() {
  final v = const <int>[];
  print(v);
}

常見修正方式

#

將關鍵字 final 替換為 const,並從初始化器中移除 const

dart
class C {
  static const f = <int>[];
}

偏好_const_字面值以建立不可變物件

#

將 'const' 文字用作 '@immutable' 類別的建構子的引數。

描述

#

當非 const 列表、映射或集合文字作為引數傳遞給在使用 @immutable 註解的類別中宣告的建構子時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為列表文字 ([1]) 正在傳遞給不可變類別中的建構子,但不是常數列表

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final f;

  const C(this.f);
}

C c = C([1]);

常見修正方式

#

如果上下文可以設為 常數上下文,則執行此操作

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final f;

  const C(this.f);
}

const C c = C([1]);

如果上下文無法設為 常數上下文,但可以使用 const 調用建構子,則在建構子調用之前新增 const

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final f;

  const C(this.f);
}

C c = const C([1]);

如果上下文無法設為 常數上下文,並且無法使用 const 調用建構子,則在集合文字之前新增關鍵字 const

dart
import 'package:meta/meta.dart';

@immutable
class C {
  final f;

  const C(this.f);
}

C c = C(const [1]);

偏好_contains

#

始終為 'false',因為 'indexOf' 始終大於或等於 -1。

始終為 'true',因為 'indexOf' 始終大於或等於 -1。

不必要地使用 'indexOf' 測試是否包含。

描述

#

當使用方法 indexOf,並且結果僅與 -10 進行比較時,分析器會產生此診斷訊息,其中語意等同於使用 contains

範例

#

以下程式碼會產生此診斷訊息,因為 if 陳述式中的條件正在檢查列表是否包含字串

dart
void f(List<String> l, String s) {
  if (l.indexOf(s) < 0) {
    // ...
  }
}

常見修正方式

#

改用 contains,必要時取反條件

dart
void f(List<String> l, String s) {
  if (l.contains(s)) {
    // ...
  }
}

偏好雙引號

#

不必要地使用單引號。

描述

#

當字串文字使用單引號 (') 但可以使用雙引號 (") 而無需額外跳脫字元且不損害可讀性時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為字串文字使用了單引號,但不需要

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

常見修正方式

#

使用雙引號代替單引號

dart
void f(String name) {
  print("Hello $name");
}

偏好_final_欄位

#

私有欄位 {0} 可以是 'final'。

描述

#

當私有欄位僅被賦值一次時,分析器會產生此診斷訊息。 欄位可以在多個建構子中初始化,但仍然會被標記,因為這些建構子中只有一個可以運行。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 _f 僅被賦值一次,在欄位的初始化器中

dart
class C {
  int _f = 1;

  int get f => _f;
}

常見修正方式

#

將欄位標記為 final

dart
class C {
  final int _f = 1;

  int get f => _f;
}

偏好使用_for元素而不是_mapFromIterable

#

從可迭代物件建構映射時,使用 'for' 元素。

描述

#

Map.fromIterable 用於建構可以使用 for 元素建構的映射時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 fromIterable 正在被用來建構可以使用 for 元素建構的映射

dart
void f(Iterable<String> data) {
  Map<String, int>.fromIterable(
    data,
    key: (element) => element,
    value: (element) => element.length,
  );
}

常見修正方式

#

使用 for 元素來建構映射

dart
void f(Iterable<String> data) {
  <String, int>{
    for (var element in data)
      element: element.length
  };
}

偏好函式宣告而不是變數

#

使用函式宣告而不是變數賦值將函式綁定到名稱。

描述

#

當閉包被賦值給區域變數,並且該區域變數在任何地方都沒有被重新賦值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為區域變數 f 被初始化為閉包,並且未被賦值任何其他值

dart
void g() {
  var f = (int i) => i * 2;
  f(1);
}

常見修正方式

#

將區域變數替換為區域函式

dart
void g() {
  int f(int i) => i * 2;
  f(1);
}

偏好泛型函式類型別名

#

在 'typedef' 中使用泛型函式類型語法。

描述

#

當 typedef 使用較舊的函式類型別名語法撰寫時,分析器會產生此診斷訊息,在該語法中,被宣告的名稱嵌入在函式類型中。

範例

#

以下程式碼會產生此診斷訊息,因為它使用了較舊的語法

dart
typedef void F<T>();

常見修正方式

#

重寫 typedef 以使用較新的語法

dart
typedef F<T> = void Function();

偏好_if_null運算子

#

當測試 'null' 時,使用 '??' 運算子而不是 '?:'。

描述

#

當條件運算式(使用 ?: 運算子)用於在區域變數為 null 時選擇不同的值時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為變數 s 正在與 null 進行比較,以便在 snull 時可以傳回不同的值

dart
String f(String? s) => s == null ? '' : s;

常見修正方式

#

改用 if-null 運算子

dart
String f(String? s) => s ?? '';

偏好初始化形式參數

#

使用初始化形式參數將參數賦值給欄位。

描述

#

當建構子參數用於初始化欄位而不進行修改時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為參數 c 僅用於設定欄位 c

dart
class C {
  int c;

  C(int c) : this.c = c;
}

常見修正方式

#

使用初始化形式參數來初始化欄位

dart
class C {
  int c;

  C(this.c);
}

偏好內嵌的_add

#

新增列表項可以內聯。

新增多個列表項可以內聯。

描述

#

當在列表文字上調用方法 addaddAll,並且要新增的元素可以包含在列表文字中時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 add 方法正在被用來新增 b,但它可以直接包含在列表文字中

dart
List<String> f(String a, String b) {
  return [a]..add(b);
}

以下程式碼會產生此診斷訊息,因為 addAll 方法正在被用來新增 b 的元素,但它可以直接包含在列表文字中

dart
List<String> f(String a, List<String> b) {
  return [a]..addAll(b);
}

常見修正方式

#

如果正在使用 add 方法,則將引數設為列表的元素並移除調用

dart
List<String> f(String a, String b) {
  return [a, b];
}

如果正在使用 addAll 方法,則對引數使用擴展運算子以將其元素新增到列表中並移除調用

dart
List<String> f(String a, List<String> b) {
  return [a, ...b];
}

偏好內插而不是撰寫字串

#

使用插值來組合字串和值。

描述

#

當字串文字和計算字串正在使用 + 運算子串連,但字串插值可以達到相同的結果時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為字串 s 使用 + 運算子與其他字串串連

dart
String f(String s) {
  return '(' + s + ')';
}

常見修正方式

#

使用字串插值

dart
String f(List<String> l) {
  return '(${l[0]}, ${l[1]})';
}

偏好_isEmpty

#

比較始終為 'false',因為長度始終大於或等於 0。

比較始終為 'true',因為長度始終大於或等於 0。

使用 'isEmpty' 而不是 'length' 來測試集合是否為空。

使用 'isNotEmpty' 而不是 'length' 來測試集合是否為空。

描述

#

當調用 Iterable.lengthMap.length 的結果與零 (0) 進行相等性比較時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為調用 length 的結果正在檢查是否等於零

dart
int f(Iterable<int> p) => p.length == 0 ? 0 : p.first;

常見修正方式

#

length 的使用替換為使用 isEmptyisNotEmpty

dart
void f(Iterable<int> p) => p.isEmpty ? 0 : p.first;

偏好_isNotEmpty

#

使用 'isNotEmpty' 而不是取反 'isEmpty' 的結果。

描述

#

當調用 Iterable.isEmptyMap.isEmpty 的結果被取反時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為調用 Iterable.isEmpty 的結果被取反

dart
void f(Iterable<int> p) => !p.isEmpty ? p.first : 0;

常見修正方式

#

重寫程式碼以使用 isNotEmpty

dart
void f(Iterable<int> p) => p.isNotEmpty ? p.first : 0;

偏好_is_not運算子

#

使用 'is!' 運算子而不是取反 'is' 運算子的值。

描述

#

分析器在前綴 ! 運算子被用來否定 is 測試的結果時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為測試 o 是否為 String 的結果,使用了前綴 ! 運算子來否定。

dart
String f(Object o) {
  if (!(o is String)) {
    return o.toString();
  }
  return o;
}

常見修正方式

#

改用 is! 運算子

dart
String f(Object o) {
  if (o is! String) {
    return o.toString();
  }
  return o;
}

偏好_Iterable.whereType

#

使用 'whereType' 來選取給定類型的元素。

描述

#

分析器在方法 Iterable.where 被用來根據元素的類型篩選元素時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為方法 where 被用來僅存取可迭代物件內的字串。

dart
Iterable<Object> f(Iterable<Object> p) => p.where((e) => e is String);

常見修正方式

#

重寫程式碼以使用 whereType

dart
Iterable<String> f(Iterable<Object> p) => p.whereType<String>();

這也可能讓您能夠收緊程式碼中的類型,或移除其他類型檢查。

偏好_null_感知運算子

#

使用可感知空值運算子 '?.',而不是明確的 'null' 比較。

描述

#

分析器在與 null 進行比較以保護成員參考時,以及在受保護的目標為 null 時,null 被用作結果時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 length 的調用受 null 比較保護,即使預設值為 null

dart
int? f(List<int>? p) {
  return p == null ? null : p.length;
}

常見修正方式

#

改用可感知空值存取運算子

dart
int? f(List<int>? p) {
  return p?.length;
}

偏好相對匯入

#

對於 'lib' 目錄中的檔案,使用相對匯入。

描述

#

分析器在位於 'lib' 目錄內的函式庫中的 import 語句,使用 package: URI 來參考同一個套件中的另一個函式庫時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為它使用了 package: URI,但本可以使用相對 URI。

dart
import 'package:my_package/bar.dart';

常見修正方式

#

使用相對 URI 來匯入函式庫

dart
import 'bar.dart';

偏好單引號

#

不必要地使用雙引號。

描述

#

分析器在字串字面值可以使用單引號 (') 而不需要額外的跳脫字元,且不會損害可讀性的情況下,卻使用了雙引號 (") 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為字串字面值使用了雙引號,但並不需要。

dart
void f(String name) {
  print("Hello $name");
}

常見修正方式

#

使用單引號來代替雙引號

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

偏好為未初始化的變數輸入類型

#

未初始化的欄位應具有明確的類型註解。

未初始化的變數應具有明確的類型註解。

描述

#

分析器在沒有初始化器的變數沒有明確的類型註解時,會發出此診斷訊息。

在沒有類型註解或初始化器的情況下,變數的類型為 dynamic,這允許將任何值賦予變數,通常會導致難以識別的錯誤。

範例

#

以下程式碼會發出此診斷訊息,因為變數 r 沒有類型註解或初始化器。

dart
Object f() {
  var r;
  r = '';
  return r;
}

常見修正方式

#

如果變數可以被初始化,則添加一個初始化器

dart
Object f() {
  var r = '';
  return r;
}

如果變數無法被初始化,則添加一個明確的類型註解

dart
Object f() {
  String r;
  r = '';
  return r;
}

偏好_void而不是_null

#

不必要地使用類型 'Null'。

描述

#

分析器在 Null 被使用在 void 會是有效選擇的位置時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為函數 f 被宣告為返回 null(在未來某個時間)。

dart
Future<Null> f() async {}

常見修正方式

#

Null 的使用替換為 void 的使用

dart
Future<void> f() async {}

提供已淘汰訊息

#

缺少棄用訊息。

描述

#

分析器在使用了 deprecated 註解而不是 Deprecated 註解時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為函數 f 使用了 deprecated 註解。

dart
@deprecated
void f() {}

常見修正方式

#

將程式碼轉換為使用較長的形式

dart
@Deprecated('Use g instead. Will be removed in 4.0.0.')
void f() {}

遞迴式_getter

#

Getter '{0}' 遞迴地返回自身。

描述

#

分析器在 getter 調用自身,導致無限迴圈時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 getter count 調用自身。

dart
class C {
  int _count = 0;

  int get count => count;
}

常見修正方式

#

更改 getter 使其不調用自身

dart
class C {
  int _count = 0;

  int get count => _count;
}

安全_pubspec_網址

#

不應使用 '{0}' 協定,因為它不安全。

描述

#

分析器在 pubspec.yaml 檔案中的 URL 使用非安全協定時,例如 http,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 pubspec.yaml 檔案包含一個 http URL。

yaml
dependencies:
  example: any
    repository: http://github.com/dart-lang/example

常見修正方式

#

更改 URL 的協定以使用安全協定,例如 https

yaml
dependencies:
  example: any
    repository: https://github.com/dart-lang/example

用於空白的_尺寸_方塊

#

使用 'SizedBox' 將空白添加到佈局中。

描述

#

分析器在僅使用 height 和/或 width 參數創建 Container 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 Container 僅具有 width 參數。

dart
import 'package:flutter/material.dart';

Widget buildRow() {
  return Row(
    children: <Widget>[
      const Text('...'),
      Container(
        width: 4,
        child: Text('...'),
      ),
      const Expanded(
        child: Text('...'),
      ),
    ],
  );
}

常見修正方式

#

Container 替換為相同尺寸的 SizedBox

dart
import 'package:flutter/material.dart';

Widget buildRow() {
  return Row(
    children: <Widget>[
      Text('...'),
      SizedBox(
        width: 4,
        child: Text('...'),
      ),
      Expanded(
        child: Text('...'),
      ),
    ],
  );
}

尺寸_方塊_收縮_展開

#

使用 'SizedBox.{0}' 以避免需要指定 'height' 和 'width'。

描述

#

分析器在 SizedBox 建構子調用同時指定 heightwidth 的值為 0.0double.infinity 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 heightwidth 均為 0.0

dart
import 'package:flutter/material.dart';

Widget build() {
  return SizedBox(
    height: 0.0,
    width: 0.0,
    child: const Text(''),
  );
}

以下程式碼會發出此診斷訊息,因為 heightwidth 均為 double.infinity

dart
import 'package:flutter/material.dart';

Widget build() {
  return SizedBox(
    height: double.infinity,
    width: double.infinity,
    child: const Text(''),
  );
}

常見修正方式

#

如果兩者都為 0.0,則使用 SizedBox.shrink

dart
import 'package:flutter/material.dart';

Widget build() {
  return SizedBox.shrink(
    child: const Text(''),
  );
}

如果兩者都為 double.infinity,則使用 SizedBox.expand

dart
import 'package:flutter/material.dart';

Widget build() {
  return SizedBox.expand(
    child: const Text(''),
  );
}

用於_文件_註解的斜線

#

對於文件註解,使用行尾形式 ('///')。

描述

#

分析器在文件註解使用區塊註解樣式(以 /***/ 分隔)時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 f 的文件註解使用了區塊註解樣式。

dart
/**
 * Example.
 */
void f() {}

常見修正方式

#

使用行尾註解樣式

dart
/// Example.
void f() {}

排序_子項_屬性_最後

#

'{0}' 參數應為 widget 建構子調用中的最後一個。

描述

#

分析器在 childchildren 參數不是 widget 類別建構子的調用中的最後一個參數時,會發出此診斷訊息。 但如果 childchildren 參數之後的所有參數都是函數表達式,則會例外。

範例

#

以下程式碼會發出此診斷訊息,因為 child 參數不是 Center 建構子調用中的最後一個參數。

dart
import 'package:flutter/material.dart';

Widget createWidget() {
  return Center(
    child: Text('...'),
    widthFactor: 0.5,
  );
}

常見修正方式

#

childchildren 參數移動到最後

dart
import 'package:flutter/material.dart';

Widget createWidget() {
  return Center(
    widthFactor: 0.5,
    child: Text('...'),
  );
}

排序_建構子_優先

#

建構子宣告應在非建構子宣告之前。

描述

#

分析器在建構子宣告之前有一個或多個非建構子宣告時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 C 的建構子出現在方法 m 之後。

dart
class C {
  void m() {}

  C();
}

常見修正方式

#

將所有建構子宣告移動到任何其他宣告之前

dart
class C {
  C();

  void m() {}
}

排序_pub_相依性

#

依賴項未按字母順序排序。

描述

#

分析器在 pubspec.yaml 檔案中的依賴項映射中的鍵未按字母順序排序時,會發出此診斷訊息。 檢查的依賴項映射為 dependenciesdev_dependenciesdependency_overrides 映射。

範例

#

以下程式碼會發出此診斷訊息,因為 dependencies 映射中的條目未排序。

yaml
dependencies:
  path: any
  collection: any

常見修正方式

#

排序條目

yaml
dependencies:
  collection: any
  path: any

排序_未命名_建構子_優先

#

未命名建構子的位置無效。

描述

#

分析器在未命名的建構子出現在命名建構子之後時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為未命名的建構子在命名建構子之後。

dart
class C {
  C.named();

  C();
}

常見修正方式

#

將未命名的建構子移動到任何其他建構子之前

dart
class C {
  C();

  C.named();
}

等於中的_測試_類型

#

在 '==' 中缺少 '{0}' 的類型測試。

描述

#

分析器在 == 運算子的覆寫中,未包含對參數值的類型測試時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為未對 other 進行類型測試。

dart
class C {
  final int f;

  C(this.f);

  @override
  bool operator ==(Object other) {
    return (other as C).f == f;
  }
}

常見修正方式

#

執行 is 測試作為計算傳回值的一部分

dart
class C {
  final int f;

  C(this.f);

  @override
  bool operator ==(Object other) {
    return other is C && other.f == f;
  }
}

在_finally中拋出

#

在 'finally' 區塊中使用 '{0}'。

描述

#

分析器在 finally 區塊內找到 throw 語句時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為在 finally 區塊內有一個 throw 語句。

dart
void f() {
  try {
    // ...
  } catch (e) {
    // ...
  } finally {
    throw 'error';
  }
}

常見修正方式

#

重寫程式碼,使 throw 語句不在 finally 區塊內

dart
void f() {
  try {
    // ...
  } catch (e) {
    // ...
  }
  throw 'error';
}

類型_初始化_形式

#

不要不必要地為初始化形式參數添加類型註解。

描述

#

分析器在初始化形式參數 (this.x) 或 super 參數 (super.x) 具有與欄位或覆寫參數相同的明確類型註解時,會發出此診斷訊息。

如果建構子參數使用 this.x 來初始化欄位,則參數的類型隱含地與欄位的類型相同。 如果建構子參數使用 super.x 來轉發到 super 建構子,則參數的類型隱含地與 super 建構子參數相同。

範例

#

以下程式碼會發出此診斷訊息,因為參數 this.c 具有與欄位 c 相同的明確類型。

dart
class C {
  int c;

  C(int this.c);
}

以下程式碼會發出此診斷訊息,因為參數 super.a 具有與超類別中的參數 a 相同的明確類型。

dart
class A {
  A(int a);
}

class B extends A {
  B(int super.a);
}

常見修正方式

#

從參數中移除類型註解

dart
class C {
  int c;

  C(this.c);
}

常數_模式中的類型_字面值

#

使用 'TypeName _' 而不是類型字面值。

描述

#

分析器在類型字面值作為模式出現時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為類型字面值被用作常數模式。

dart
void f(Object? x) {
  if (x case num) {
    // ...
  }
}

常見修正方式

#

如果類型字面值旨在匹配給定類型的物件,則使用變數模式

dart
void f(Object? x) {
  if (x case num _) {
    // ...
  }
}

或物件模式

dart
void f(Object? x) {
  if (x case num()) {
    // ...
  }
}

如果類型字面值旨在匹配類型字面值,則將其寫為常數模式

dart
void f(Object? x) {
  if (x case const (num)) {
    // ...
  }
}

未等待的_Future

#

此表達式計算的 'Future' 缺少 'await'。

描述

#

分析器在 Future 的實例從 async(或 async*)方法或函數內的調用返回,且 future 既未被等待,也未傳遞給 unawaited 函數時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為函數 g 返回 future,但 future 未被等待。

dart
Future<void> f() async {
  g();
}

Future<int> g() => Future.value(0);

常見修正方式

#

如果 future 需要在後續程式碼執行之前完成,則在調用之前添加 await

dart
Future<void> f() async {
  await g();
}

Future<int> g() => Future.value(0);

如果 future 不需要在後續程式碼執行之前完成,則將返回 Future 的調用包裝在 unawaited 函數的調用中

dart
import 'dart:async';

Future<void> f() async {
  unawaited(g());
}

Future<int> g() => Future.value(0);

文件_註解中非預期的_HTML

#

角括號將被解釋為 HTML。

描述

#

分析器在文件註解包含未經允許的例外角括號文本 (<...>) 時,會發出此診斷訊息。

此類文本被 markdown 解釋為 HTML 標籤,這通常不是預期的。

請參閱 lint 規則描述 以取得允許的例外列表。

範例

#

以下程式碼會發出此診斷訊息,因為文件註解包含文本 <int>,這不是允許的例外之一。

dart
/// Converts a List<int> to a comma-separated String.
String f(List<int> l) => '';

常見修正方式

#

如果文本旨在成為程式碼跨度的一部分,則在程式碼周圍添加反引號

dart
/// Converts a `List<int>` to a comma-separated String.
String f(List<int> l) => '';

如果文本旨在成為連結的一部分,則在程式碼周圍添加方括號

dart
/// Converts a [List<int>] to a comma-separated String.
String f(List<int> l) => '';

如果文本旨在按原樣列印,包括角括號,則在角括號之前添加反斜線跳脫字元

dart
/// Converts a List\<int\> to a comma-separated String.
String f(List<int> l) => '';

字串_內插中不必要的_大括號

#

字串插值中不必要的花括號。

描述

#

分析器在帶有花括號的字串插值被用來插入簡單的識別字,且後續沒有字母數字文本時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為插值元素 ${s} 在不需要時使用了花括號。

dart
String f(String s) {
  return '"${s}"';
}

常見修正方式

#

移除不必要的花括號

dart
String f(String s) {
  return '"$s"';
}

不必要的_const

#

不必要的 'const' 關鍵字。

描述

#

分析器在 常數上下文 中使用關鍵字 const 時,會發出此診斷訊息。 由於它是隱含的,因此不需要此關鍵字。

範例

#

以下程式碼會發出此診斷訊息,因為列表字面值中的關鍵字 const 是不需要的。

dart
const l = const <int>[];

由於變數宣告上的關鍵字 const,列表是隱含的 const

常見修正方式

#

移除不必要的關鍵字

dart
const l = <int>[];

不必要的_建構子_名稱

#

不必要的 '.new' 建構子名稱。

描述

#

分析器在對未命名建構子的參考使用 .new 時,會發出此診斷訊息。 唯一需要 .new 的地方是在建構子拆卸中。

範例

#

以下程式碼會發出此診斷訊息,因為 .new 被用來指稱未命名建構子,但在這裡是不需要的。

dart
var o = Object.new();

常見修正方式

#

移除不必要的 .new

dart
var o = Object();

不必要的_final

#

區域變數不應標記為 'final'。

描述

#

分析器在區域變數被標記為 final 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為區域變數 c 被標記為 final

dart
void f(int a, int b) {
  final c = a + b;
  print(c);
}

常見修正方式

#

如果變數沒有類型註解,則將 final 替換為 var

dart
void f(int a, int b) {
  var c = a + b;
  print(c);
}

如果變數具有類型註解,則移除 final 修飾詞

dart
void f(int a, int b) {
  int c = a + b;
  print(c);
}

不必要的_getter_和_setter

#

不必要地使用 getter 和 setter 來包裝欄位。

描述

#

分析器在 getter 和 setter 配對返回並設置欄位的值,而沒有任何額外處理時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為名為 c 的 getter/setter 配對僅公開名為 _c 的欄位。

dart
class C {
  int? _c;

  int? get c => _c;

  set c(int? v) => _c = v;
}

常見修正方式

#

將欄位設為 public 並移除 getter 和 setter

dart
class C {
  int? c;
}

不必要的_ignore

#

診斷訊息 '{0}' 未在此位置產生,因此不需要忽略它。

診斷訊息 '{0}' 未在此檔案中產生,因此不需要忽略它。

描述

#

分析器在指定忽略未產生的診斷訊息時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 unused_local_variable 診斷訊息未在被忽略的位置報告。

dart
// ignore: unused_local_variable
void f() {}

常見修正方式

#

移除忽略註解

dart
void f() {}

不必要的_lambda

#

閉包應該是拆卸。

描述

#

分析器在閉包(lambda)可以被拆卸替換時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為傳遞給 forEach 的閉包僅包含對函數 print 的調用,並使用閉包的參數。

dart
void f(List<String> strings) {
  strings.forEach((string) {
    print(string);
  });
}

常見修正方式

#

將閉包替換為正在調用函數或方法的拆卸,並使用閉包

dart
void f(List<String> strings) {
  strings.forEach(print);
}

不必要的_late

#

不必要的 'late' 修飾詞。

描述

#

分析器在具有初始化器的頂層變數或靜態欄位被標記為 late 時,會發出此診斷訊息。 頂層變數和靜態欄位隱含地為 late,因此它們不需要被明確標記。

範例

#

以下程式碼會發出此診斷訊息,因為靜態欄位 c 具有修飾詞 late,即使它具有初始化器。

dart
class C {
  static late String c = '';
}

常見修正方式

#

移除關鍵字 late

dart
class C {
  static String c = '';
}

不必要的_library_名稱

#

函式庫名稱不是必要的。

描述

#

分析器在 library 指令指定名稱時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 library 指令包含一個名稱。

dart
library some.name;

class C {}

常見修正方式

#

library 指令中移除名稱

dart
library;

class C {}

如果函式庫有任何部分,則任何使用函式庫名稱的 part of 宣告都應更新為使用函式庫的 URI。

不必要的_new

#

不必要的 'new' 關鍵字。

描述

#

分析器在使用關鍵字 new 來調用建構子時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為關鍵字 new 被用來調用來自 Object 的未命名建構子。

dart
var o = new Object();

常見修正方式

#

移除關鍵字 new

dart
var o = Object();

不必要的_null_感知_賦值

#

不必要地賦值 'null'。

描述

#

分析器在可感知空值賦值的右側是 null 字面值時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為可感知空值運算子被用來將 null 賦值給 s,而 s 已經是 null

dart
void f(String? s) {
  s ??= null;
}

常見修正方式

#

如果應將非 null 值賦值給左側運算元,則更改右側

dart
void f(String? s) {
  s ??= '';
}

如果沒有非 null 值賦值給左側運算元,則移除賦值

dart
void f(String? s) {
}

if_null_運算子中不必要的_null

#

不必要地使用 '??' 和 'null'。

描述

#

分析器在 ?? 運算子的右側運算元是字面值 null 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 ?? 運算子的右側運算元是 null

dart
String? f(String? s) => s ?? null;

常見修正方式

#

如果應將非 null 值用於右側運算元,則更改右側

dart
String f(String? s) => s ?? '';

如果沒有非 null 值用於右側運算元,則移除運算子和右側運算元

dart
String? f(String? s) => s;

final_變數_宣告不必要的_可為 Null

#

類型可以是非可空類型。

描述

#

分析器在 final 欄位或變數具有可空類型,但被初始化為非可空值時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為 final 變數 i 具有可空類型 (int?),但永遠不會是 null

dart
final int? i = 1;

常見修正方式

#

將類型設為非可空類型

dart
final int i = 1;

不必要的_覆寫

#

不必要的覆寫。

描述

#

分析器在實例成員覆寫繼承成員,但僅使用完全相同的參數調用覆寫成員時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為方法 D.m 除了調用覆寫方法之外,沒有做任何其他事情。

dart
class C {
  int m(int x) => x;
}

class D extends C {
  @override
  int m(int x) => super.m(x);
}

常見修正方式

#

如果該方法應執行比覆寫方法更多的操作,則實作缺失的功能

dart
class C {
  int m(int x) => x;
}

class D extends C {
  @override
  int m(int x) => super.m(x) + 1;
}

如果應通過更改傳回類型或一個或多個參數類型、使其中一個參數為 covariant、具有文件註解或具有其他註解來修改覆寫方法,則更新程式碼

dart
import 'package:meta/meta.dart';

class C {
  int m(int x) => x;
}

class D extends C {
  @mustCallSuper
  @override
  int m(int x) => super.m(x);
}

如果覆寫方法沒有更改或增強程式碼的語義,則移除它

dart
class C {
  int m(int x) => x;
}

class D extends C {}

不必要的_括號

#

不必要地使用括號。

描述

#

分析器在括號的使用不會影響程式碼語義時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為二元表達式周圍的括號是不必要的。

dart
int f(int a, int b) => (a + b);

常見修正方式

#

移除不必要的括號

dart
int f(int a, int b) => a + b;

不必要的_原始_字串

#

不必要地使用原始字串。

描述

#

分析器在字串字面值被標記為原始字串(以 r 作為前綴),但使字串成為原始字串不會更改字串的值時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為字串字面值在沒有 r 的情況下與有 r 的情況下具有相同的值。

dart
var s = r'abc';

常見修正方式

#

移除字串字面值前面的 r

dart
var s = 'abc';

不必要的_陳述式

#

不必要的語句。

描述

#

分析器在表達式語句沒有明顯效果時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為兩個調用傳回值的加法沒有明顯效果。

dart
void f(int Function() first, int Function() second) {
  first() + second();
}

常見修正方式

#

如果不需要計算表達式,則移除它

dart
void f(int Function() first, int Function() second) {
}

如果需要表達式的值,則使用它,可能首先將其賦值給區域變數

dart
void f(int Function() first, int Function() second) {
  print(first() + second());
}

如果需要執行表達式的部分,則移除不必要的部分

dart
void f(int Function() first, int Function() second) {
  first();
  second();
}

不必要的_字串_跳脫字元

#

字串字面值中不必要的跳脫字元。

描述

#

分析器在字串中的字元被跳脫,但跳脫它們是不必要時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為單引號不需要在雙引號分隔的字串內被跳脫。

dart
var s = "Don\'t use a backslash here.";

常見修正方式

#

移除不必要的反斜線

dart
var s = "Don't use a backslash here.";

不必要的_字串_內插

#

不必要地使用字串插值。

描述

#

分析器在字串字面值包含單個 String 值變數的插值,且沒有其他字元時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為字串字面值包含單個插值,且不包含插值之外的任何字元。

dart
String f(String s) => '$s';

常見修正方式

#

將字串字面值替換為插值的內容

dart
String f(String s) => s;

不必要的_this

#

不必要的 'this.' 限定詞。

描述

#

分析器在使用關鍵字 this 來存取未被遮蔽的成員時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為使用 this 來存取欄位 _f 是不必要的。

dart
class C {
  int _f = 2;

  int get f => this._f;
}

常見修正方式

#

移除 this.

dart
class C {
  int _f = 2;

  int get f => _f;
}

展開中不必要的_to_list

#

在展開運算符中不必要地使用 'toList'。

描述

#

分析器在 toList 被用來將 Iterable 轉換為 List,緊接著對列表應用展開運算符時,會發出此診斷訊息。 展開運算符可以應用於任何 Iterable,因此轉換是不必要的。

範例

#

以下程式碼會發出此診斷訊息,因為 toListmap 的結果上被調用,而 map 的結果是一個 Iterable,展開運算符可以直接應用於它。

dart
List<String> toLowercase(List<String> strings) {
  return [
    ...strings.map((String s) => s.toLowerCase()).toList(),
  ];
}

常見修正方式

#

移除 toList 的調用

dart
List<String> toLowercase(List<String> strings) {
  return [
    ...strings.map((String s) => s.toLowerCase()),
  ];
}

不必要的_底線

#

不必要地使用多個底線。

描述

#

分析器在未使用的變數以多個底線(例如 __)命名時,會發出此診斷訊息。 可以改用單個 _ 萬用字元變數。

範例

#

以下程式碼會發出此診斷訊息,因為 __ 參數未使用。

dart
void function(int __) { }

常見修正方式

#

將名稱替換為單個底線

dart
void function(int _) { }

不相關的_類型_相等性_檢查

#

運算元的類型 ('{0}') 不是被匹配的值 ('{1}') 的子類型或超類型。

右側運算元的類型 ('{0}') 不是左側運算元 ('{1}') 的子類型或超類型。

描述

#

分析器在比較兩個物件,且兩個物件的靜態類型都不是另一個物件的子類型時,會發出此診斷訊息。

這樣的比較通常會傳回 false,並且可能無法反映程式設計師的意圖。

可能會有誤報。 例如,名為 Point 的類別可能具有名為 CartesianPointPolarPoint 的子類別,它們都不是另一個的子類型,但測試實例的相等性可能仍然是適當的。

作為一個具體案例,來自 package:fixnum 的類別 Int64Int32 允許將實例與 int 進行比較,前提是 int 在右側。 此案例已明確地被診斷訊息允許,但其他此類案例則不然。

範例

#

以下程式碼會發出此診斷訊息,因為字串 s 正在與整數 1 進行比較。

dart
bool f(String s) {
  return s == 1;
}

常見修正方式

#

將其中一個運算元替換為與另一個運算元相容的內容

dart
bool f(String s) {
  return s.length == 1;
}

不安全的_變異數

#

此類型是不安全的:類型參數出現在非協變位置。

描述

#

分析器在實例成員具有結果類型,該結果類型在封閉宣告的類型參數中是逆變或不變時,會發出此診斷訊息。 變數的結果類型是其類型,而 getter 或方法的結果類型是其傳回類型。 此 lint 會警告此類成員,因為它們很可能在運行時導致類型檢查失敗,而在調用站點沒有靜態警告或錯誤。

範例

#

以下程式碼會發出此診斷訊息,因為 X 作為 f 類型中的參數類型出現,這是此類型參數的逆變發生。

dart
class C<X> {
  bool Function(X) f;
  C(this.f);
}

這是不安全的:如果 c 具有靜態類型 C<num> 和運行時類型 C<int>,則 c.f 將會拋出例外。 因此,每個調用 c.f(a) 也會拋出例外,即使在 a 作為 c.f 的參數具有正確類型的情況下也是如此。

常見修正方式

#

如果 linted 成員是或可以是私有的,則您可能可以強制執行它永遠不會在除 this 之外的任何其他接收器上存取。 這足以確保不會發生運行時類型錯誤。 例如

dart
class C<X> {
  // NB: Ensure manually that `_f` is only accessed on `this`.
  // ignore: unsafe_variance
  bool Function(X) _f;

  C(this._f);

  // We can write a forwarding method to allow clients to call `_f`.
  bool f(X x) => _f(x);
}

您可以通過為 linted 成員使用更通用的類型來消除不安全的變異數。 在這種情況下,您可能需要在調用站點檢查運行時類型並執行向下轉型。

dart
class C<X> {
  bool Function(Never) f;
  C(this.f);
}

如果 c 具有靜態類型 C<num>,則您可以測試類型。 例如,c.f is bool Function(num)。 如果它具有該類型,您可以安全地使用 num 類型的參數調用它。

您也可以通過使用更通用的類型(如 Function)來消除不安全的變異數,這本質上是函數的 dynamic 類型。

dart
class C<X> {
  Function f;
  C(this.f);
}

這將使 c.f(a) 在動態上安全:它將在且僅在參數 a 沒有函數要求的類型時拋出例外。 這比原始版本更好,因為它不會因為靜態類型不匹配而拋出例外。 它只會在為了健全性原因 *必須* 拋出例外時才拋出例外。

同步使用_BuildContext

#

不要在非相關的 'mounted' 檢查保護下,跨非同步間隙使用 'BuildContext'。

不要跨非同步間隙使用 'BuildContext'。

描述

#

分析器在 StatefulWidget 在非同步間隙之後引用 BuildContext,且未首先檢查 mounted 屬性時,會發出此診斷訊息。

儲存 BuildContext 以供稍後使用可能會導致難以診斷的崩潰。 非同步間隙隱含地儲存 BuildContext,使其在診斷時容易被忽略。

範例

#

以下程式碼會發出此診斷訊息,因為 contextawait 之後被傳遞給建構子。

dart
import 'package:flutter/material.dart';

class MyWidget extends Widget {
  void onButtonTapped(BuildContext context) async {
    await Future.delayed(const Duration(seconds: 1));
    Navigator.of(context).pop();
  }
}

常見修正方式

#

如果可以移除非同步間隙,請執行此操作

dart
import 'package:flutter/material.dart';

class MyWidget extends Widget {
  void onButtonTapped(BuildContext context) {
    Navigator.of(context).pop();
  }
}

如果無法移除非同步間隙,則使用 mounted 來保護 context 的使用

dart
import 'package:flutter/material.dart';

class MyWidget extends Widget {
  void onButtonTapped(BuildContext context) async {
    await Future.delayed(const Duration(seconds: 1));
    if (context.mounted) {
      Navigator.of(context).pop();
    }
  }
}

使用_彩色_方塊

#

使用 'ColoredBox' 而不是僅具有 'Color' 的 'Container'。

描述

#

分析器在創建僅設置顏色的 Container 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為設置的容器的唯一屬性是 color

dart
import 'package:flutter/material.dart';

Widget build() {
  return Container(
    color: Colors.red,
    child: const Text('hello'),
  );
}

常見修正方式

#

Container 替換為 ColoredBox

dart
import 'package:flutter/material.dart';

Widget build() {
  return ColoredBox(
    color: Colors.red,
    child: const Text('hello'),
  );
}

使用_裝飾_方塊

#

使用 'DecoratedBox' 而不是僅具有 'Decoration' 的 'Container'。

描述

#

分析器在創建僅設置裝飾的 Container 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為設置的容器的唯一屬性是 decoration

dart
import 'package:flutter/material.dart';

Widget buildArea() {
  return Container(
    decoration: const BoxDecoration(
      color: Colors.red,
      borderRadius: BorderRadius.all(
        Radius.circular(5),
      ),
    ),
    child: const Text('...'),
  );
}

常見修正方式

#

Container 替換為 DecoratedBox

dart
import 'package:flutter/material.dart';

Widget buildArea() {
  return DecoratedBox(
    decoration: const BoxDecoration(
      color: Colors.red,
      borderRadius: BorderRadius.all(
        Radius.circular(5),
      ),
    ),
    child: const Text('...'),
  );
}

Flutter_顏色使用完整的_十六進位_

#

'Color' 的實例應使用 8 位十六進制整數(例如 '0xFFFFFFFF')創建。

描述

#

分析器在 Color 類別的建構子的參數是未表示為 8 位十六進制整數的字面值整數時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為參數 (1) 未表示為 8 位十六進制整數。

dart
import 'package:flutter/material.dart';

Color c = Color(1);

常見修正方式

#

將表示形式轉換為 8 位十六進制整數

dart
import 'package:flutter/material.dart';

Color c = Color(0x00000001);

參數使用_函式_類型_語法

#

使用泛型函數類型語法來宣告參數 '{0}'。

描述

#

分析器在使用較舊樣式的函數值參數語法時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為函數值參數 f 使用了較舊樣式的語法宣告。

dart
void g(bool f(String s)) {}

常見修正方式

#

使用泛型函數類型語法來宣告參數

dart
void g(bool Function(String) f) {}

使用_if_null將_null轉換為_布林值

#

使用 if-null 運算子將 'null' 轉換為 'bool'。

描述

#

分析器在可空 bool 值表達式與布林字面值進行比較(使用 ==!=)時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為可空布林變數 btrue 進行比較。

dart
void f(bool? b) {
  if (b == true) {
    // Treats `null` as `false`.
  }
}

常見修正方式

#

重寫條件以改用 ??

dart
void f(bool? b) {
  if (b ?? false) {
    // Treats `null` as `false`.
  }
}

在_widget_建構子中使用_key

#

公共 widget 的建構子應具有名為 'key' 的命名參數。

描述

#

分析器在不是對其函式庫私有的 Widget 子類別中的建構子,沒有名為 key 的參數時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為類別 MyWidget 的建構子沒有名為 key 的參數。

dart
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  MyWidget({required int height});
}

以下程式碼會發出此診斷訊息,因為類別 MyWidget 的預設建構子沒有名為 key 的參數。

dart
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {}

常見修正方式

#

將名為 key 的參數添加到建構子,必要時顯式宣告建構子

dart
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  MyWidget({super.key, required int height});
}

私有_欄位和_變數使用_late

#

對於具有非可空類型的私有成員,使用 'late'。

描述

#

分析器在私有欄位或變數被標記為可空類型,但每個參考都假定變數永遠不是 null 時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為私有頂層變數 _i 是可空的,但每個參考都假定它不會是 null

dart
void f() {
  _i!.abs();
}

int? _i;

常見修正方式

#

將變數或欄位標記為非可空和 late,以表明它將始終被賦值為非 null 值

dart
void f() {
  _i.abs();
}

late int _i;

使用_具名_常數

#

使用常數 '{0}' 而不是返回相同物件的建構子。

描述

#

分析器在創建的常數具有與已知的 const 變數相同的值時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為有一個已知的 const 欄位 (Duration.zero) 其值與建構子調用將評估為的值相同。

dart
Duration d = const Duration(seconds: 0);

常見修正方式

#

將建構子調用替換為對已知 const 變數的參考

dart
Duration d = Duration.zero;

使用_null_感知_元素

#

使用可感知空值標記 '?' 而不是通過 'if' 進行 null 檢查。

描述

#

分析器在集合字面值中使用 null 檢查而不是可感知空值標記時,會發出此診斷訊息。

範例

#

以下程式碼會發出此診斷訊息,因為使用 null 檢查來決定是否應將 x 插入列表中,而可感知空值標記 '?' 會更簡潔且更簡略。

dart
f(int? x) => [if (x != null) x];

常見修正方式

#

將 null 檢查替換為可感知空值標記 '?'

dart
f(int? x) => [?x];

使用_原始_字串

#

使用原始字串以避免使用跳脫字元。

描述

#

分析器在包含跳脫字元且沒有插值的字串字面值,可以被標記為原始字串以避免需要跳脫字元時,會發出此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為字串包含跳脫字元,如果將字串設為原始字串,則不需要跳脫字元

dart
var s = 'A string with only \\ and \$';

常見修正方式

#

將字串標記為原始字串,並移除不必要的反斜線

dart
var s = r'A string with only \ and $';

盡可能使用_rethrow

#

使用 'rethrow' 重新擲回捕獲的例外。

描述

#

當使用 throw 運算式而非 rethrow 陳述式擲回捕獲的例外時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為捕獲的例外 e 是使用 throw 運算式擲回的

dart
void f() {
  try {
    // ...
  } catch (e) {
    throw e;
  }
}

常見修正方式

#

使用 rethrow 而非 throw

dart
void f() {
  try {
    // ...
  } catch (e) {
    rethrow;
  }
}

使用_setter來變更_屬性

#

此方法用於變更屬性。

描述

#

當方法用於設定欄位的值,或函式用於設定最上層變數的值,而沒有其他用途時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為方法 setF 用於設定欄位 _f 的值,且沒有執行其他工作

dart
class C {
  int _f = 0;

  void setF(int value) => _f = value;
}

常見修正方式

#

將方法轉換為 setter

dart
class C {
  int _f = 0;

  set f(int value) => _f = value;
}

使用_字串_緩衝區

#

使用字串緩衝區而非 '+' 來組成字串。

描述

#

當在迴圈內將值串連到字串,而未使用 StringBuffer 執行串連時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為字串 result 是在 for 迴圈內透過重複串連計算而得的

dart
String f() {
  var result = '';
  for (int i = 0; i < 10; i++) {
    result += 'a';
  }
  return result;
}

常見修正方式

#

使用 StringBuffer 來計算結果

dart
String f() {
  var buffer = StringBuffer();
  for (int i = 0; i < 10; i++) {
    buffer.write('a');
  }
  return buffer.toString();
}

在_part_of_指示詞中使用_字串

#

part-of 指令使用程式庫名稱。

描述

#

part of 指令使用程式庫名稱來參照該部分所屬的程式庫時,分析器會產生此診斷訊息。

範例

#

假設有名為 lib.dart 的檔案包含以下內容

dart
library lib;

part 'test.dart';

以下程式碼會產生此診斷訊息,因為 part of 指令使用程式庫的名稱,而非其所屬程式庫的 URI

dart
part of lib;

常見修正方式

#

使用 URI 來參照程式庫

dart
part of 'lib.dart';

使用_super_參數

#

參數 '{0}' 可以是 super 參數。

參數 '{0}' 可以是 super 參數。

描述

#

當建構子的參數傳遞給 super 建構子,而未被參照或修改,且未使用 super 參數時,分析器會產生此診斷訊息。

範例

#

以下程式碼會產生此診斷訊息,因為 B 的建構子的參數僅用作 super 建構子的引數

dart
class A {
  A({int? x, int? y});
}
class B extends A {
  B({int? x, int? y}) : super(x: x, y: y);
}

常見修正方式

#

使用 super 參數來傳遞引數

dart
class A {
  A({int? x, int? y});
}
class B extends A {
  B({super.x, super.y});
}

使用_截斷_除法

#

使用截斷除法。

描述

#

當將兩個數字相除的結果使用 toInt 轉換為整數時,分析器會產生此診斷訊息。

Dart 有內建的整數除法運算子,既更有效率又更簡潔。

範例

#

以下程式碼會產生此診斷,因為除以 xy 的結果使用 toInt 轉換為整數

dart
int divide(int x, int y) => (x / y).toInt();

常見修正方式

#

使用整數除法運算子 (~/)

dart
int divide(int x, int y) => x ~/ y;

有效的_正規表示式

#

無效的正規表示式語法。

描述

#

當傳遞給類別 RegExp 的預設建構子的字串不包含有效的正規表示式時,分析器會產生此診斷訊息。

使用無效語法建立的正規表示式會在執行階段擲回 FormatException

範例

#

以下程式碼會產生此診斷訊息,因為正規表示式無效

dart
var r = RegExp(r'(');

常見修正方式

#

修正正規表示式

dart
var r = RegExp(r'\(');

void_檢查

#

指派給 'void' 類型的變數。

描述

#

當值指派給 void 類型的變數時,分析器會產生此診斷訊息。

無法存取此類變數的值,因此指派沒有任何意義。

範例

#

以下程式碼會產生此診斷訊息,因為欄位 value 的類型為 void,但正在將值指派給它

dart
class A<T> {
  T? value;
}

void f(A<void> a) {
  a.value = 1;
}

以下程式碼會產生此診斷訊息,因為方法 m 中參數 p 的類型為 void,但在調用中正在將值指派給它

dart
class A<T> {
  void m(T p) { }
}

void f(A<void> a) {
  a.m(1);
}

常見修正方式

#

如果變數的類型不正確,則變更變數的類型

dart
class A<T> {
  T? value;
}

void f(A<int> a) {
  a.value = 1;
}

如果變數的類型正確,則移除指派

dart
class A<T> {
  T? value;
}

void f(A<void> a) {}