目錄

avoid_dynamic_calls

避免在 dynamic 目標上進行方法呼叫或屬性存取。

此規則從 Dart 2.12 開始提供。

詳細資訊

#

請務必避免在明確或隱式靜態類型為 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