跳到主要內容

avoid_dynamic_calls

穩定

避免對 dynamic 目標進行方法呼叫或屬性訪問。

詳情

#

建議 避免對顯式或隱式靜態型別為 dynamic 的物件進行方法呼叫或屬性訪問。動態呼叫在每種執行時環境和編譯器中的處理方式略有不同,但大多數生產模式(甚至某些開發模式)都與動態呼叫相關的編譯尺寸和執行時效能開銷。

此外,型別為 dynamic 的目標會停用大多數靜態分析,這意味著與正確進行靜態型別檢查的 Dart 程式碼相比,它更容易導致執行時 NoSuchMethodErrorTypeError

Object? 上存在的方法和屬性除外:

  • a.hashCode
  • a.runtimeType
  • a.noSuchMethod(someInvocation)
  • a.toString()

... 這些成員在基於 web 的執行時中是動態排程的,但在基於 VM 的執行時中則不是。此外,它們非常常見,如果禁止使用 any.toString()any == true 等,將會非常不便。

請注意,儘管 Function 是一種型別,但其語義與 dynamic 幾乎相同,並且對型別為 Function 的物件進行呼叫也會觸發此 lint 規則。

允許在轉換表示式(as dynamicas Function)上進行動態呼叫。

錯誤示例

dart
void explicitDynamicType(dynamic object) {
  print(object.foo());
}

void implicitDynamicType(object) {
  print(object.foo());
}

abstract class SomeWrapper {
  T doSomething<T>();
}

void inferredDynamicType(SomeWrapper wrapper) {
  var object = wrapper.doSomething();
  print(object.foo());
}

void callDynamic(dynamic function) {
  function();
}

void functionType(Function function) {
  function();
}

正確示例

dart
void explicitType(Fooable object) {
  object.foo();
}

void castedType(dynamic object) {
  (object as Fooable).foo();
}

abstract class SomeWrapper {
  T doSomething<T>();
}

void inferredType(SomeWrapper wrapper) {
  var object = wrapper.doSomething<Fooable>();
  object.foo();
}

void functionTypeWithParameters(Function() function) {
  function();
}

啟用

#

要啟用 avoid_dynamic_calls 規則,請在您的 analysis_options.yaml 檔案中,在 linter > rules 下新增 avoid_dynamic_calls

analysis_options.yaml
yaml
linter:
  rules:
    - avoid_dynamic_calls

如果您使用 YAML 對映語法來配置 linter 規則,請在 linter > rules 下新增 avoid_dynamic_calls: true

analysis_options.yaml
yaml
linter:
  rules:
    avoid_dynamic_calls: true