内容
内容 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注释的映射参数中的值不是以下整数类型之一时,分析器会产生此诊断信息。

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

示例

#

以下代码会产生此诊断信息,因为映射项的值为Array<Uint8>,这不是有效的整数类型。

dart
import 'dart:ffi';

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

常见修复方法

#

在映射中使用其中一个有效类型作为值。

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' 类不能标记为 'abstract',因为它已经是隐式抽象的。

描述

#

当使用修饰符abstractsealed同时声明一个类时,分析器会生成此诊断信息。密封类隐式地是抽象的,因此不允许显式使用这两个修饰符。

示例

#

以下代码会生成此诊断信息,因为类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;

不明确的扩展成员访问

#

在 {1} 中定义了一个名为 '{0}' 的成员,并且没有更具体的成员。

描述

#

当代码引用对象的成员(例如,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} 中定义。

描述

#

当引用在两个或多个导入库中声明的名称时,分析器会生成此诊断信息。

示例

#

给定一个定义类(本例中为C)的库(a.dart

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) {}

集合或映射字面量同时存在

#

该字面量不能是映射或集合,因为它至少包含一个字面量映射条目或一个扩展运算符扩展“Map”,以及至少一个既不是映射条目也不是集合的元素。

描述

#

由于映射和集合字面量使用相同的定界符({}),分析器会查看类型参数和元素以确定你指的是哪种字面量。当没有类型参数时,分析器会使用元素的类型。如果所有元素都是字面量映射条目,并且所有扩展运算符都扩展了Map,那么它就是一个Map。如果没有任何元素是字面量映射条目,并且所有扩展运算符都扩展了Iterable,那么它就是一个Set。如果两者都不符合,那么它就是模棱两可的。

当至少一个元素是字面量映射条目或一个扩展运算符扩展Map,并且至少一个元素既不是映射条目也不是集合时,分析器会生成此诊断信息,这使得分析器无法确定你是在编写映射字面量还是集合字面量。

示例

#

以下代码会生成此诊断信息

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

列表b只能扩展到集合中,映射ac只能扩展到映射中,而字面量不能同时是两者。

常见修复方法

#

解决此问题的两种常见方法。第一种方法是删除所有一种或另一种类型的扩展元素,以便元素保持一致。在这种情况下,这可能意味着删除列表并决定如何处理现在未使用的参数。

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};

集合或映射字面量任一存在

#

该字面量必须是映射或集合,但元素没有足够的信息来进行类型推断。

描述

#

由于映射和集合字面量使用相同的定界符({}),分析器会查看类型参数和元素来确定您指的是哪种字面量。当没有类型参数并且所有元素都是展开元素(这两种字面量中都允许)时,分析器会使用正在展开的表达式的类型。如果所有表达式都具有类型 Iterable,则它是一个集合字面量;如果它们都具有类型 Map,则它是一个映射字面量。

当没有一个正在展开的表达式具有允许分析器确定您是在编写映射字面量还是集合字面量的类型时,就会产生此诊断信息。

示例

#

以下代码会生成此诊断信息

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

问题出现是因为没有类型参数,并且没有关于 ab 类型的信息。

常见修复方法

#

有三种常见的解决此问题的方法。第一种是在字面量中添加类型参数。例如,如果字面量意图是一个映射字面量,您可以编写类似以下内容

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;
}

指针字段上的注解

#

结构类中类型为 '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);
}

参数类型不可赋值

#

参数类型“{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”初始化器。

描述

#

当重定向构造函数(将构造函数重定向到同一类中的另一个构造函数的构造函数)在初始化列表中包含断言时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为未命名的构造函数是重定向构造函数,并且在初始化列表中也包含断言

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

常见修复方法

#

如果不需要断言,则将其删除

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

如果需要断言,则将构造函数转换为工厂构造函数

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

常见修复方法

#

更改资产映射,使其包含一个path字段,该字段具有字符串值(有效的 POSIX 风格文件路径)

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

资产不是字符串或映射

#

资产值需要是文件路径(字符串)或映射。

描述

#

当资产值不是字符串或映射时,分析器会产生此诊断信息。

示例

#

以下代码产生此诊断信息,因为资产值是一个列表。

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映射,使其包含一个值为字符串(有效的 POSIX 风格文件路径)的path值。

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

对“不存储”的赋值

#

'{0}' 被标记为 'doNotStore',不应该被分配给字段或顶级变量。

描述

#

当显式或隐式地用 doNotStore 注解标记的函数(包括方法和 getter)的值存储在字段或顶级变量中时,分析器会产生此诊断信息。

示例

#

以下代码产生此诊断信息,因为函数f的值被存储在顶级变量x中。

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

@doNotStore
int f() => 1;

var x = f();

常见修复方法

#

用调用生成值的函数来替换对字段或变量的引用。

对常量的赋值

#

常量变量不能被分配值。

描述

#

当分析器发现对具有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 的调用,但没有 setter,因为具有相同名称的字段被声明为finalconst时,会产生此诊断信息。

示例

#

以下代码产生此诊断信息,因为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);
}

对 final 的赋值,没有 setter

#

类 '{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);
}

异步 for in 错误的上下文中

#

async for-in 循环只能在 async 函数中使用。

描述

#

当在函数或方法中找到 async for-in 循环时,分析器会产生此诊断,其主体未标记为asyncasync*

示例

#

以下代码产生此诊断是因为f的函数体没有标记为asyncasync*,但f包含一个异步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

#

在“late”局部变量的初始化器中不能使用“await”表达式。

描述

#

当使用late修饰符的局部变量在其初始化器中使用await表达式时,分析器会产生此诊断。

示例

#

以下代码产生此诊断是因为在v的初始化器中使用了await表达式,而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

#

对于扩展类型不是“Future”子类型的表达式,不能使用“await”表达式。

描述

#

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;
}

如果扩展类型旨在可等待,则在implements子句中添加Future(或Future的子类型)(如果不存在则添加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;
  }
}

主体可能正常完成,捕获错误

#

此“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) {});
}

主体可能正常完成,可为空

#

此函数的可空返回类型为“{0}”,但结束时没有返回值。

描述

#

当方法或函数可以通过从末尾掉落隐式返回null时,分析器会生成此诊断信息。虽然这是有效的 Dart 代码,但最好让null的返回显式。

示例

#

以下代码会生成此诊断信息,因为函数f隐式返回null

dart
String? f() {}

常见修复方法

#

如果null的返回是故意的,则将其显式化

dart
String? f() {
  return 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、类型参数或导入前缀的声明中使用的名称是内置标识符时,分析器会生成此诊断信息。内置标识符不能用于命名任何这些类型的声明。

示例

#

以下代码会生成此诊断信息,因为mixin是一个内置标识符

dart
extension mixin on int {}

常见修复方法

#

为声明选择一个不同的名称。

回调不能使用 TypedData

#

FFI 回调不能接受类型化数据参数或返回值。

描述

#

Pointer.fromFunction的调用,NativeCallable的构造函数之一具有类型化数据参数或返回值时,分析器会生成此诊断信息。

类型化数据解包仅在叶 FFI 调用的参数上受支持。

有关 FFI 的更多信息,请参阅 使用 dart:ffi 进行 C 互操作

示例

#

以下代码会生成此诊断信息,因为g的参数类型是类型化数据。

dart
import 'dart:ffi';
import 'dart:typed_data';

void f(Uint8List i) {}

void g() {
  Pointer.fromFunction<Void Function(Pointer<Uint8>)>(f);
}

常见修复方法

#

使用Pointer类型代替。

dart
import 'dart:ffi';

void f(Pointer<Uint8> i) {}

void g() {
  Pointer.fromFunction<Void Function(Pointer<Uint8>)>(f);
}

调用不能返回 TypedData

#

FFI 调用不能返回类型化数据。

描述

#

Pointer.asFunctionDynamicLibrary.lookupFunction@Native的返回类型是类型化数据时,分析器会生成此诊断信息。

类型化数据解包仅在叶 FFI 调用的参数上受支持。

有关 FFI 的更多信息,请参阅 使用 dart:ffi 进行 C 互操作

示例

#

以下代码会生成此诊断信息,因为 dart 函数签名包含类型化数据,但isLeaf参数为false

dart
import 'dart:ffi';
import 'dart:typed_data';

void f(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
  p.asFunction<Uint8List Function()>();
}

常见修复方法

#

使用Pointer类型代替。

dart
import 'dart:ffi';

void f(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
  p.asFunction<Pointer<Uint8> Function()>();
}

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 后面表达式静态类型的子类型的静态类型时,分析器会生成此诊断。

示例

#

以下代码会生成此诊断,因为 1 是一个 int,它不是 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;
  }
}

从可为空的强制转换总是失败

#

此强制转换将始终抛出异常,因为可空局部变量“{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;

类用作 mixin

#

类 '{0}' 不能用作 mixin,因为它既不是 mixin 类也不是 mixin。

描述

#

当在 with 子句中使用既不是 mixin class 也不是 mixin 的类时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为类 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' 映射文字中的键。

来自延迟库的常量值不能用作 'const' 构造函数中的值。

来自延迟库的常量值不能用作 'const' 列表文字中的值。

来自延迟库的常量值不能用作 'const' 映射文字中的值。

来自延迟库的常量值不能用作 'const' 集合文字中的值。

描述

#

当显式(因为它以 const 关键字为前缀)或隐式(因为它出现在 常量上下文 中)为常量的集合文字包含在使用延迟导入导入的库中声明的值时,分析器会生成此诊断信息。常量在编译时进行评估,而来自延迟库的值在编译时不可用。

有关更多信息,请查看 延迟加载库

示例

#

给定一个定义常量 zero 的文件 a.dart

dart
const zero = 0;

以下代码会生成此诊断信息,因为常量列表文字包含 a.zero,它使用 deferred 导入进行导入

dart
import 'a.dart' deferred as a;

var l = const [a.zero];

常见修复方法

#

如果集合文字不需要是常量,则删除 const 关键字

dart
import 'a.dart' deferred as a;

var l = [a.zero];

如果集合需要是常量并且必须引用导入的常量,则从导入中删除关键字 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 通过实现 AEnum 作为超接口。

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) {}
}

常量构造函数参数类型不匹配

#

类型为 '{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,但类中的字段初始化为非常量值时,分析器会生成此诊断。

示例

#

以下代码会生成此诊断,因为字段 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();
}

常量构造函数使用非常量超类

#

常量构造函数不能调用 '{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 字段

#

无法为具有非final字段的类定义const构造函数。

描述

#

当构造函数被标记为const构造函数,但构造函数是在至少包含一个非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类的实例。

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变量的变量时,分析器会产生此诊断。

示例

#

以下代码会产生此诊断,因为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变量时,分析器会产生此诊断。常量在编译时进行评估,而延迟库中的值在编译时不可用。

有关更多信息,请查看 延迟加载库

示例

#

以下代码会产生此诊断,因为变量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;

常量实例字段

#

只有静态字段可以声明为常量。

描述

#

当实例字段被标记为常量时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为f是一个实例字段

dart
class C {
  const int f = 3;
}

常见修复方法

#

如果该字段需要是一个实例字段,则删除关键字const,或将其替换为final

dart
class C {
  final int f = 3;
}

如果该字段确实应该是一个常量字段,则将其设为静态字段

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

常量映射键不是原始相等性

#

常量映射中的键的类型不能重写'=='运算符或'hashCode',但类'{0}'却重写了。

描述

#

当常量映射文字中用作键的对象的类实现==运算符、hashCode获取器或两者时,分析器会生成此诊断信息。常量映射的实现同时使用==运算符和hashCode获取器,因此除了从Object继承的实现之外,任何其他实现都需要在编译时执行任意代码,这是不支持的。

示例

#

以下代码会生成此诊断信息,因为常量映射包含一个类型为C的键,而类C重写了==的实现

dart
class C {
  const C();

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

const map = {C() : 0};

以下代码会生成此诊断信息,因为常量映射包含一个类型为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的实现,请将映射设为非常量

dart
class C {
  const C();

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

final map = {C() : 0};

常量未初始化

#

常量'{0}'必须初始化。

描述

#

当声明为常量的变量没有初始化器时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为c没有初始化

dart
const c;

常见修复方法

#

添加一个初始化器

dart
const c = 'c';

常量集合元素不是原始相等性

#

(以前称为const_set_element_type_implements_equals)

常量集合中的元素不能重写'=='运算符或'hashCode',但类型'{0}'却重写了。

描述

#

当用作常量集合文字元素的对象类实现==运算符、hashCode获取器或两者时,分析器会生成此诊断信息。常量集合的实现同时使用==运算符和hashCode获取器,因此除了从Object继承的实现之外,任何其他实现都需要在编译时执行任意代码,这是不支持的。

示例

#

以下代码会生成此诊断信息,因为常量集合包含一个类型为C的元素,而类C重写了==的实现。

dart
class C {
  const C();

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

const set = {C()};

以下代码会生成此诊断信息,因为常量集合包含一个类型为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的实现,则将集合设为非常量。

dart
class C {
  const C();

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

final set = {C()};

常量展开预期列表或集合

#

在此展开中需要一个列表或集合。

描述

#

当常量列表或集合中展开运算符的表达式计算结果不是列表或集合时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为list1的值为null,既不是列表也不是集合。

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

常见修复方法

#

将表达式更改为计算结果为常量列表或常量集合的表达式。

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

常量展开预期映射

#

在此展开中需要一个映射。

描述

#

当常量映射中展开运算符的表达式计算结果不是映射时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为map1的值为null,不是映射。

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

常见修复方法

#

将表达式更改为计算结果为常量映射的表达式。

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

常量使用非常量

#

正在调用的构造函数不是常量构造函数。

描述

#

当使用const关键字调用未标记为const的构造函数时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为A中的构造函数不是常量构造函数。

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();

常量使用非常量参数

#

常量创建的参数必须是常量表达式。

描述

#

当使用不是常量表达式的参数调用常量构造函数时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为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 调用中的类型参数时,分析器会生成此诊断信息。这是不允许的,因为类型参数的值(将在运行时使用的实际类型)在编译时无法知道。

示例

#

以下代码会生成此诊断信息,因为类型参数 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 语句的标签 lcontinue 语句中使用

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

常见修复方法

#

找到另一种方法来实现所需的控制流;例如,通过引入一个重新执行 switch 语句的循环。

创建结构体或联合体

#

'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();
}

无用代码

#

无用代码。

描述

#

当分析器发现代码不会被执行时,会产生此诊断信息,因为执行永远不会到达该代码。

示例

#

以下代码会产生此诊断信息,因为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 (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 块不会被执行,因为 '{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,因此右侧永远不会被计算。

示例

#

以下代码会产生此诊断信息,因为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;
    }
  }
}

默认列表构造函数

#

启用空安全时,默认的'List'构造函数不可用。

描述

#

当分析器在已选择加入空安全的代码中找到对类List的默认构造函数的使用时,它会生成此诊断。

示例

#

假设以下代码已选择加入空安全,它会生成此诊断,因为它使用默认的List构造函数

dart
var l = List<int>();

常见修复方法

#

如果没有提供初始大小,则将代码转换为使用列表文字

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) {
}

重定向工厂构造函数中的默认值

#

重定向到另一个构造函数的工厂构造函数中不允许使用默认值。

描述

#

当重定向到另一个构造函数的工厂构造函数为可选参数指定默认值时,分析器会生成此诊断。

示例

#

以下代码会生成此诊断,因为A中的工厂构造函数为可选参数x指定了默认值

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

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

常见修复方法

#

从工厂构造函数中删除默认值

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

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

请注意,此修复可能会更改省略可选参数时使用的值。如果发生这种情况,并且该更改是一个问题,则考虑在工厂方法中将可选参数设为必需参数

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();
}

未赋值的延迟局部变量

#

延迟局部变量 '{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);
}

依赖项字段不是映射

#

预期 '{0}' 字段的值为一个映射。

描述

#

dependenciesdev_dependencies键的值不是映射时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为顶层dependencies键的值是一个列表

yaml
name: example
dependencies:
  - meta

常见修复方法

#

使用映射作为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在类或混合的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 具有内置的整数除法运算符,它既更高效又更简洁。

示例

#

以下代码会生成此诊断信息,因为使用toIntxy相除的结果转换为整数。

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;

重复忽略

#

诊断“{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}) {}
}

重复的部分

#

库已经包含一个具有 URI“{0}”的部分。

描述

#

当一个文件在多个部分指令中被引用时,分析器会产生此诊断。

示例

#

给定一个包含以下内容的文件part.dart

dart
part of lib;

以下代码产生此诊断,因为文件part.dart被包含多次。

dart
library lib;

part 'part.dart';
part 'part.dart';

常见修复方法

#

删除除第一个重复部分指令之外的所有指令。

dart
library lib;

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;
  }
}

模式中重复的剩余元素

#

列表或映射模式中最多允许一个剩余元素。

描述

#

当列表或映射模式中存在多个剩余模式时,分析器会产生此诊断信息。剩余模式将捕获所有未被其他子模式匹配的值,因此后续的剩余模式将变得不必要,因为没有剩余的值可以捕获。

示例

#

以下代码会产生此诊断信息,因为列表模式中有两个剩余模式。

dart
void f(List<int> x) {
  if (x case [0, ..., ...]) {}
}

常见修复方法

#

删除除一个之外的所有剩余模式。

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}' 已在此模式中定义。

描述

#

当逻辑与模式的分支声明一个在同一模式的早期分支中已声明的变量时,分析器会产生此诊断信息。

示例

#

以下代码会产生此诊断信息,因为变量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 (var a, 0) && (0, var b)) {
    print(a + b);
  }
}

如果您只需要在一个分支中捕获匹配的值,请从除一个分支之外的所有分支中删除变量模式。

dart
void f((int, int) r) {
  if (r case (var a, 0) && (0, _)) {
    print(a);
  }
}

空映射模式

#

映射模式必须至少包含一个条目。

描述

#

当映射模式为空时,分析器会产生此诊断信息。

示例

#

以下代码产生此诊断信息,因为映射模式为空。

dart
void f(Map<int, String> x) {
  if (x case {}) {}
}

常见修复方法

#

如果模式应该匹配任何映射,则将其替换为对象模式。

dart
void f(Map<int, String> x) {
  if (x case 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) {}

空结构体

#

类 '{0}' 不能为空,因为它是的子类 '{1}'。

描述

#

当的子类 StructUnion 没有任何字段时,分析器会产生此诊断信息。没有空 StructUnion 是不支持的。

有关 FFI 的更多信息,请参阅 使用 dart:ffi 进行 C 互操作

示例

#

以下代码产生此诊断信息,因为类 C,它扩展了 Struct,没有声明任何字段。

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 {}

如果类不意图是一个结构体,则删除或更改扩展子句。

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._();
}

枚举混合使用实例变量

#

应用于枚举的混入不能具有实例变量。

描述

#

当应用于枚举的混入声明一个或多个实例变量时,分析器会产生此诊断信息。这是不允许的,因为枚举值是常量,并且枚举中的构造函数无法初始化任何混入的字段。

示例

#

以下代码产生此诊断信息,因为混入M定义了实例字段x

dart
mixin M {
  int x = 0;
}

enum E with M {
  a
}

常见修复方法

#

如果您需要应用混入,请将所有实例字段更改为 getter 和 setter 对,并在必要时在枚举中实现它们。

dart
mixin M {
  int get x => 0;
}

enum E with M {
  a
}

如果您不需要应用混入,请将其删除。

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 之外的其他名称。

常量集中存在相等元素

#

常量集合文字中的两个元素不能相等。

描述

#

当常量集合文字中的两个元素具有相同的值时,分析器会产生此诊断信息。集合只能包含每个值一次,这意味着其中一个值是不必要的。

示例

#

以下代码产生此诊断信息,因为字符串 'a' 被指定了两次。

dart
const Set<String> set = {'a', 'a'};

常见修复方法

#

删除其中一个重复的值。

dart
const Set<String> set = {'a'};

请注意,文字集合会保留其元素的顺序,因此选择要删除的元素可能会影响迭代器返回元素的顺序。

集中存在相等元素

#

集合字面量中的两个元素不应该相等。

描述

#

当非常量集合中的元素与同一集合中之前的元素相同时,分析器会生成此诊断信息。如果两个元素相同,则第二个值将被忽略,这使得拥有这两个元素毫无意义,并且可能表明存在错误。

示例

#

以下代码会生成此诊断信息,因为元素 1 出现了两次

dart
const a = 1;
const b = 1;
var s = <int>{a, b};

常见修复方法

#

如果两个元素都应该包含在集合中,则更改其中一个元素

dart
const a = 1;
const b = 2;
var s = <int>{a, b};

如果只需要其中一个元素,则删除不需要的那个元素

dart
const a = 1;
var s = <int>{a};

请注意,文字集合会保留其元素的顺序,因此选择要删除的元素可能会影响迭代器返回元素的顺序。

常量映射中存在相等键

#

常量映射字面量中的两个键不能相等。

描述

#

当常量映射中的键与同一映射中之前的键相同时,分析器会生成此诊断信息。如果两个键相同,则第二个值将覆盖第一个值,这使得拥有这两个键值对毫无意义。

示例

#

以下代码会生成此诊断信息,因为键 1 被使用了两次

dart
const map = <int, String>{1: 'a', 2: 'b', 1: 'c', 4: 'd'};

常见修复方法

#

如果两个条目都应该包含在映射中,则更改其中一个键使其不同

dart
const map = <int, String>{1: 'a', 2: 'b', 3: 'c', 4: 'd'};

如果只需要其中一个条目,则删除不需要的那个条目

dart
const map = <int, String>{1: 'a', 2: 'b', 4: 'd'};

请注意,字面量映射会保留其条目的顺序,因此选择删除哪个条目可能会影响迭代器返回键和值的顺序。

映射中存在相等键

#

映射字面量中的两个键不应该相等。

描述

#

当非常量映射中的键与同一映射中之前的键相同时,分析器会生成此诊断信息。如果两个键相同,则第二个值将覆盖第一个值,这使得拥有这两个键值对毫无意义,并且可能表明存在错误。

示例

#

以下代码会生成此诊断信息,因为键 ab 的值相同

dart
const a = 1;
const b = 1;
var m = <int, String>{a: 'a', b: 'b'};

常见修复方法

#

如果两个条目都应该包含在映射中,则更改其中一个键

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'};

请注意,字面量映射会保留其条目的顺序,因此选择删除哪个条目可能会影响迭代器返回键和值的顺序。

映射模式中存在相等键

#

映射模式中的两个键不能相等。

描述

#

当映射模式包含多个具有相同名称的键时,分析器会生成此诊断信息。同一个键不能匹配两次。

示例

#

以下代码会生成此诊断信息,因为键 '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>[];

预期一个集合类型参数

#

集合字面量需要一个类型参数或没有类型参数,但找到了 {0} 个。

描述

#

当集合字面量具有多个类型参数时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为集合字面量具有三个类型参数,而它最多只能有一个类型参数

dart
var s = <int, String, int>{0, 'a', 1};

常见修复方法

#

删除除一个以外的所有类型参数

dart
var s = <int>{0, 1};

预期两个映射模式类型参数

#

映射模式需要两个类型参数或没有类型参数,但找到了 {0} 个。

描述

#

当映射模式具有一个类型参数或多个类型参数时,分析器会生成此诊断信息。映射模式可以具有两个类型参数或零个类型参数,但不能具有其他数量的类型参数。

示例

#

以下代码会生成此诊断信息,因为映射模式 (<int>{}) 具有一个类型参数

dart
void f(Object x) {
  if (x case <int>{0: _}) {}
}

常见修复方法

#

添加或删除类型参数,直到有 2 个或没有类型参数

dart
void f(Object x) {
  if (x case <int, int>{0: _}) {}
}

预期两个映射类型参数

#

映射字面量需要两个类型参数或没有类型参数,但找到了 {0} 个。

描述

#

当映射字面量具有一个或多个类型参数时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为映射字面量具有三个类型参数,而它可以具有两个或零个类型参数

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 {}

如果被导出的库(未启用空安全性的库)本身导出了一个已启用空安全性的库,那么您的库可以间接导出已启用空安全性的库中的符号。您可以在库的导出指令中添加一个隐藏组合器,隐藏未启用空安全性的库中声明的所有名称。

导出非库

#

导出的库 '{0}' 不能包含部分指令。

描述

#

当导出指令引用的是部分而不是库时,分析器会产生此诊断信息。

示例

#

给定一个包含以下内容的文件part.dart

dart
part of lib;

以下代码会产生此诊断信息,因为文件 part.dart 是一个部分,而只有库可以被导出

dart
library lib;

export 'part.dart';

常见修复方法

#

删除导出指令,或将 URI 更改为包含部分的库的 URI。

映射中的表达式

#

表达式不能在映射字面量中使用。

描述

#

当分析器在看似映射字面量的代码中发现表达式而不是映射条目时,它会产生此诊断信息。

示例

#

以下代码会生成此诊断信息

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、setter 或方法。

扩展声明对象成员

#

扩展不能声明与“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 形式参数

#

扩展类型构造函数不能声明超类形式参数。

描述

#

当扩展类型中的构造函数具有超类参数时,分析器会生成此诊断信息。超类参数无效,因为扩展类型没有超类。

示例

#

以下代码会生成此诊断信息,因为命名构造函数 n 包含超类参数

dart
extension type E(int i) {
  E.n(this.i, super.foo);
}

常见修复方法

#

如果需要该参数,请将超类参数替换为普通参数

dart
extension type E(int i) {
  E.n(this.i, String foo);
}

如果不需要该参数,请删除超类参数

dart
extension type E(int i) {
  E.n(this.i);
}

扩展类型构造函数带 super 调用

#

扩展类型构造函数不能包含超类初始化器。

描述

#

当扩展类型中的构造函数在初始化列表中包含对超类构造函数的调用时,分析器会生成此诊断信息。由于扩展类型没有超类,因此没有构造函数可以调用。

示例

#

以下代码会生成此诊断信息,因为构造函数 E.n 在其初始化列表中调用了超类构造函数

dart
extension type E(int i) {
  E.n() : i = 0, super.n();
}

常见修复方法

#

删除对超类构造函数的调用

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 {}

常见修复方法

#

从实现子句中删除不允许的类型

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 {}

常见修复方法

#

通过从参与循环的至少一个类型的实现子句中删除一个类型来打破循环

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 {}

常见修复方法

#

如果表示类型正确,则删除或替换实现子句中的类型

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 {}

或从实现子句中删除实现的类型

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) {}

扩展类型表示类型为底层

#

表示类型不能是底部类型。

描述

#

当扩展类型的表示类型为 底部类型 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 子类的字段有多个注解描述字段的原生类型时,分析器会生成此诊断信息。

有关 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);
}

extra_size_annotation_carray

#

“数组”必须只有一个“数组”注解。

描述

#

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;
}

字段由多个初始化器初始化

#

字段“{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;
}

字段初始化器工厂构造函数

#

初始化形式参数不能在工厂构造函数中使用。

描述

#

当工厂构造函数具有初始化形式参数时,分析器会生成此诊断信息。工厂构造函数不能为字段分配值,因为没有创建实例;因此,没有要分配的字段。

示例

#

以下代码会生成此诊断信息,因为工厂构造函数使用初始化形式参数

dart
class C {
  int? f;

  factory C(this.f) => throw 0;
}

常见修复方法

#

用普通参数替换初始化形式参数。

dart
class C {
  int? f;

  factory C(int f) => throw 0;
}

结构体中的字段初始化器

#

'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();
}

字段初始化器不可赋值

#

初始化程序类型 '{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.zero(它重定向到构造函数 C)有一个初始化形式参数,用于初始化字段 f

dart
class C {
  int f;

  C(this.f);

  C.zero(this.f) : this(f);
}

以下代码会生成此诊断信息,因为构造函数 C.zero(它重定向到构造函数 C)有一个初始化器,用于初始化字段 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' 和 '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' 和 'Union' 子类的字段必须标记为外部。

描述

#

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}' 是最终的,并且在声明时被赋予了一个值,因此它不能被设置为一个新值。

描述

#

当一个最终字段被初始化两次时,分析器会产生此诊断信息:一次是在声明时,另一次是在构造函数的参数中。

示例

#

以下代码产生此诊断信息,因为字段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 未初始化

#

最终变量 '{0}' 必须被初始化。

描述

#

当一个最终字段或变量没有被初始化时,分析器会产生此诊断信息。

示例

#

以下代码产生此诊断信息,因为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 在构造函数中未初始化

#

所有最终变量都必须被初始化,但 '{0}' 和 '{1}' 没有。

所有最终变量都必须被初始化,但 '{0}' 没有。

所有最终变量都必须被初始化,但 '{0}'、'{1}' 和其他 {2} 个没有。

描述

#

当一个类定义了一个或多个没有初始化器的最终实例字段,并且至少有一个构造函数没有初始化这些字段时,分析器会产生此诊断信息。所有最终实例字段在实例创建时都必须被初始化,无论是通过字段的初始化器还是通过构造函数。

示例

#

以下代码会生成此诊断信息

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 字段不是映射

#

'flutter' 字段的值应为一个映射。

描述

#

flutter键的值不是一个映射时,分析器会产生此诊断信息。

示例

#

以下代码会产生此诊断信息,因为顶级 flutter 键的值是一个字符串。

yaml
name: example
flutter: true

常见修复方法

#

如果您需要指定 Flutter 特定的选项,请将值更改为一个映射。

yaml
name: example
flutter:
  uses-material-design: true

如果您不需要指定 Flutter 特定的选项,请删除 flutter 键。

yaml
name: example

for-in-of 循环中元素类型无效

#

在 'for' 循环中使用的类型 '{0}' 必须实现 '{1}',其类型参数可以分配给 '{2}'。

描述

#

当 for-in 循环中的 IterableStream 的元素类型无法分配给循环变量时,分析器会产生此诊断信息。

示例

#

以下代码会产生此诊断信息,因为 <String>[] 的元素类型为 String,而 String 无法分配给 e 的类型 (int)。

dart
void f() {
  for (int e in <String>[]) {
    print(e);
  }
}

常见修复方法

#

如果循环变量的类型正确,请更新可迭代对象的类型。

dart
void f() {
  for (int e in <int>[]) {
    print(e);
  }
}

如果可迭代对象的类型正确,请更新循环变量的类型。

dart
void f() {
  for (String e in <String>[]) {
    print(e);
  }
}

for-in-of 循环中类型无效

#

在 'for' 循环中使用的类型 '{0}' 必须实现 '{1}'。

描述

#

当 for-in 循环中 in 后面的表达式类型不是 Iterable 的子类时,分析器会产生此诊断信息。

示例

#

以下代码会产生此诊断信息,因为 m 是一个 Map,而 Map 不是 Iterable 的子类。

dart
void f(Map<String, String> m) {
  for (String s in m) {
    print(s);
  }
}

常见修复方法

#

用产生可迭代值的表达式替换该表达式。

dart
void f(Map<String, String> m) {
  for (String s in m.values) {
    print(s);
  }
}

for-in 循环使用常量变量

#

for-in 循环变量不能是 'const'。

描述

#

当 for-in 循环中声明的循环变量被声明为 const 时,分析器会产生此诊断信息。该变量不能是 const,因为该值无法在编译时计算。

示例

#

以下代码会产生此诊断信息,因为循环变量 x 被声明为 const

dart
void f() {
  for (const x in [0, 1, 2]) {
    print(x);
  }
}

常见修复方法

#

如果有类型注解,请从声明中删除 const 修饰符。

如果没有类型,请用 finalvar 或类型注解替换 const 修饰符。

dart
void f() {
  for (final x in [0, 1, 2]) {
    print(x);
  }
}

泛型方法类型实例化在动态类型上

#

对类型为 'dynamic' 的接收者的方法撕裂不能具有类型参数。

描述

#

当从类型为 dynamic 的接收器中分离实例方法时,分析器会生成此诊断信息,并且分离包含类型参数。由于分析器无法知道方法有多少个类型参数,或者它是否具有任何类型参数,因此它无法验证类型参数是否正确。因此,不允许使用类型参数。

示例

#

以下代码会生成此诊断信息,因为 p 的类型为 dynamic,并且 m 的分离具有类型参数

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;
}

泛型结构体子类

#

类 '{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*' 的函数必须具有返回类型,该类型是 'Stream' 的超类型,其中 'T' 是某种类型。

描述

#

当函数主体具有 async* 修饰符,但函数的返回类型既不是 Stream 也不是 Stream 的超类型时,分析器会生成此诊断信息。

示例

#

以下代码产生此诊断信息,因为函数 `f` 的主体具有 `async*` 修饰符,即使返回值类型 `int` 不是 `Stream` 的超类型。

dart
int f() async* {}

常见修复方法

#

如果函数应该是异步的,则将返回值类型更改为 `Stream` 或 `Stream` 的超类型。

dart
Stream<int> f() async* {}

如果函数应该是同步的,则删除 `async*` 修饰符。

dart
int f() => 0;

异步返回类型非法

#

标记为 `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;

具体枚举成员非法

#

在实现 `Enum` 的类中,不能声明名为 `{0}` 的具体实例成员。

在实现 `Enum` 的类中,不能从 `{1}` 继承名为 `{0}` 的具体实例成员。

描述

#

当枚举声明、实现 `Enum` 的类或具有 `Enum` 超类约束的混合类声明或继承名为 `index`、`hashCode` 或 `==` 的具体实例成员时,分析器会产生此诊断信息。

示例

#

以下代码产生此诊断信息,因为枚举 `E` 声明了一个名为 `index` 的实例 getter。

dart
enum E {
  v;

  int get index => 0;
}

以下代码产生此诊断信息,因为类 `C` 实现 `Enum`,并声明了一个名为 `hashCode` 的实例字段。

dart
abstract class C implements Enum {
  int hashCode = 0;
}

以下代码产生此诊断信息,因为类 `C` 通过类 `A` 间接实现 `Enum`,并声明了一个名为 `hashCode` 的实例 getter。

dart
abstract class A implements Enum {}

abstract class C implements A {
  int get hashCode => 0;
}

以下代码产生此诊断信息,因为混合类 `M` 在 `on` 子句中具有 `Enum`,并声明了一个名为 `==` 的显式运算符。

dart
mixin M on Enum {
  bool operator ==(Object other) => false;
}

常见修复方法

#

重命名冲突的成员。

dart
enum E {
  v;

  int get getIndex => 0;
}

枚举值非法

#

在实现 `Enum` 的类中,不能声明名为 `values` 的实例成员。

在实现 `Enum` 的类中,不能从 `{0}` 继承名为 `values` 的实例成员。

描述

#

当实现 `Enum` 的类或具有 `Enum` 超类约束的 mixin 具有名为 `values` 的实例成员时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为实现 `Enum` 的类 `C` 声明了一个名为 `values` 的实例字段。

dart
abstract class C implements Enum {
  int get values => 0;
}

以下代码会生成此诊断信息,因为实现 `Enum` 的类 `B` 从 `A` 继承了一个名为 `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*' 的函数必须具有一个返回类型,该类型是 'Iterable' 的超类型,其中 'T' 是某种类型。

描述

#

当函数体具有 `sync*` 修饰符,但函数的返回类型既不是 `Iterable` 也不是 `Iterable` 的超类型时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为函数 `f` 的主体具有 'sync*' 修饰符,但返回类型 `int` 不是 `Iterable` 的超类型。

dart
int f() sync* {}

常见修复方法

#

如果函数应该返回一个可迭代对象,则将返回类型更改为 `Iterable` 或 `Iterable` 的超类型。

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 的名称,则添加一个导入(带有前缀),用于声明它的库。

否则,要么用现有类或 mixin 的名称替换 `implements` 子句中的名称,要么从 `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 {}

隐式超类初始化器缺少参数

#

来自“{0}”的隐式调用无名构造函数具有必需参数。

描述

#

当构造函数隐式调用来自超类的无名构造函数,超类的无名构造函数具有必需参数,并且没有与必需参数相对应的超参数时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为类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();
}

常见修复方法

#

如果您可以在子类中的构造函数中添加参数,请添加与超类构造函数中的必需参数相对应的超参数。新参数可以是必需的

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});
}

如果您无法在子类中的构造函数中添加参数,请使用必需参数添加显式超构造函数调用。

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;
}

使用 load 函数导入延迟库

#

导入的库定义了一个名为“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}”是旧版库,不应该导入到空安全库中。

描述

#

当空安全的库导入非空安全的库时,分析器会生成此诊断信息。

示例

#

给定一个包含以下内容的文件a.dart

dart
// @dart = 2.9

class A {}

以下代码会生成此诊断信息,因为空安全的库正在导入非空安全的库

dart
import 'a.dart';

A? f() => null;

常见修复方法

#

如果您可以将导入的库迁移为空安全库,则迁移它并更新或删除迁移库的语言版本。

如果您无法迁移导入的库,则导入的库需要使用 2.12 之前的语言版本,因为在该版本中,空安全默认启用。

导入非库

#

导入的库“{0}”不能包含 part-of 指令。

描述

#

当将 部分文件 导入库时,分析器会生成此诊断信息。

示例

#

假设有一个名为 part.dart部分文件,其中包含以下内容

dart
part of lib;

以下代码会生成此诊断信息,因为导入的文件不能包含 part-of 指令

dart
library lib;

import 'part.dart';

常见修复方法

#

导入包含 部分文件 的库,而不是 部分文件 本身。

继承不一致

#

超接口没有为“{0}”提供有效的覆盖:{1}。

描述

#

当一个类继承了两个或多个成员的冲突签名,并且没有提供满足所有继承签名的实现时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为 C 继承了 Am 的声明,而该实现与从 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;
}

从工厂访问实例成员

#

无法从工厂构造函数访问实例成员。

描述

#

当工厂构造函数包含对实例成员的非限定引用时,分析器会生成此诊断信息。在生成式构造函数中,类的实例是在执行构造函数体之前创建和初始化的,因此可以将实例绑定到 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 位双精度数:'{0}'。

描述

#

当一个整数字面量被隐式转换为双精度浮点数,但无法在不溢出或丢失精度的情况下表示为 64 位双精度浮点数时,分析器会生成此诊断信息。如果上下文需要 double 类型,则整数字面量会隐式转换为双精度浮点数。

示例

#

以下代码会生成此诊断信息,因为整数 9223372036854775807 无法精确地表示为双精度浮点数。

dart
double x = 9223372036854775807;

常见修复方法

#

如果您需要使用精确值,请使用 BigInt 类来表示该值。

dart
var x = BigInt.parse('9223372036854775807');

如果您需要使用双精度浮点数,请将值更改为可以精确表示的值。

dart
double x = 9223372036854775808;

整数字面量超出范围

#

整数字面量 {0} 无法在 64 位中表示。

描述

#

当一个整数字面量的值太大(正数)或太小(负数)而无法在 64 位字中表示时,分析器会生成此诊断信息。

示例

#

以下代码会生成此诊断信息,因为该值无法在 64 位中表示。

dart
var x = 9223372036854775810;

常见修复方法

#

如果您需要表示当前值,请将其包装在 BigInt 类的实例中。

dart
var x = BigInt.parse('9223372036854775810');

注释无效

#

注解必须是常量变量引用或常量构造函数调用。

描述

#

当发现一个注解使用的是既不是标记为 const 的变量,也不是 const 构造函数的调用时,分析器会生成此诊断信息。

获取器不能用作注解。

示例

#

以下代码会生成此诊断信息,因为变量 v 不是 const 变量。

dart
var v = 0;

@v
void f() {
}

以下代码会生成此诊断信息,因为 f 不是变量。

dart
@f
void f() {
}

以下代码会生成此诊断信息,因为 f 不是构造函数。

dart
@f()
void f() {
}

以下代码会生成此诊断信息,因为 g 是一个获取器。

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 () {}

如果导入需要延迟,并且存在另一个合适的常量,请使用该常量代替延迟库中的常量。

来自延迟库的注释无效

#

延迟库中的常量值不能用作注释。

描述

#

当使用延迟导入的库中的常量作为注释时,分析器会生成此诊断信息。注释在编译时进行评估,而延迟库中的常量在编译时不可用。

有关更多信息,请查看 延迟加载库

示例

#

以下代码会生成此诊断信息,因为常量pi用作注释,而库dart:math被导入为deferred

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列表中包含一个不是发布托管依赖项的包时,分析器会生成此诊断信息。

要了解有关不同类型的依赖项来源的更多信息,请查看 包依赖项

示例

#

以下代码会产生此诊断信息,因为对包 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');
}

工厂方法声明无效

#

工厂方法 '{0}' 必须具有返回值类型。

描述

#

当用factory注解的方法具有void的返回值类型时,分析器会生成此诊断。

示例

#

以下代码会生成此诊断,因为方法createCfactory注解,但没有返回值

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 {}

工厂方法实现无效

#

工厂方法 '{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 {}

工厂名称无效,不是类

#

工厂构造函数的名称必须与紧邻的类的名称相同。

描述

#

当工厂构造函数的名称与周围类的名称不同时,分析器会生成此诊断。

示例

#

以下代码会生成此诊断,因为工厂构造函数的名称(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);

结构体中的字段类型无效

#

结构类中的字段不能具有类型“{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

字面量注释无效

#

只有 const 构造函数可以具有 @literal 注解。

描述

#

literal 注解应用于 const 构造函数以外的任何内容时,分析器会产生此诊断信息。

示例

#

以下代码会生成此诊断,因为构造函数不是 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体必须是同步的。

示例

#

以下代码会生成此诊断,因为setterx的体被标记为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”只能应用于具体的实例成员。

描述

#

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,因此不能使用空感知运算符“{0}”。

接收者不能为null,因此空感知运算符“{0}”是不必要的。

描述

#

当在已知为非空的可接收者上使用空感知运算符(?.?..?[?..[...?)时,分析器会生成此诊断。

示例

#

以下代码会生成此诊断,因为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后面的空感知运算符会短路lengthisEven的求值。换句话说,如果snull,则lengthisEven都不会被调用;如果s不为null,则length不能返回null值。无论哪种情况,isEven都不能在null值上调用,因此空感知运算符不是必需的。有关更多详细信息,请参阅了解空安全

以下代码产生此诊断信息,因为s不能为null

dart
void f(Object? o) {
  var s = o as String;
  s?.length;
}

尽管o可以为null,但s不能为null的原因是