我应该将所有方法参数标记为最终参数并指定类型吗

Ale*_*tin 4 dart flutter

有效的 dart 指定顶级变量应final在适用时使用: https: //dart-lang.github.io/linter/lints/prefer_final_fields.html

但是,我找不到有关方法参数的任何信息。

Flutter repo 的代码函数大多是参数未标记的函数final,包括build我见过的所有被重写的方法。

就性能和应用程序重量而言,以下哪一项更好:

@override build(context)

@override build(BuildContext context)

@override build(final BuildContext context)

也许重写函数应该以与超级函数相同的方式定义?build像上面这样可以推断类型的重写函数和其他命名/未命名函数(除了不设置类型使变量动态化之外)之间有什么区别吗,Flutter repo 也是这样写的:

static double _flingDistancePenetration(double t) { // t is not final, although treated as immutable
 return (1.2 * t * t * t) - (3.27 * t * t) + (_initialVelocityPenetration * t);
}
Run Code Online (Sandbox Code Playgroud)

我见过这个关于Java的问题:Why would one mark local Variables and methodparameters as "final" in Java? ,而且,虽然我同意最重要的答案,但我完全不知道为什么 Flutter repo 不这样做。

jam*_*lin 6

关于参数类型:是的,始终包含它们。否则,您的参数可能是dynamic1,这会产生运行时开销并且没有类型安全性。您还希望您的 API 明确指定它期望的参数类型。

关于final:这是一个基于意见的问题,我的意见是,虽然我同意 lint prefer_final_fields,但我不同意prefer_final_localslint。我认为添加final局部变量(包括函数/方法参数)是没有意义的。

  • 与相关 Java 问题的得票最高的答案相反,任何半点像样的编译器都应该能够轻松确定局部变量是否被重新分配。如果那里有任何优化机会,编译器应该能够为您做到这一点。

  • 在像 Dart 这样的语言中,实现通常与接口内联(与 C 或 C++ 等语言相反,它们有单独的头文件来声明接口),添加final参数是视觉噪音。它不向呼叫者提供任何有用的信息。

  • 无论如何,您不应该单方面标记所有函数/方法参数final。有时重新分配参数是合适的。例如,如果您的函数需要对其参数执行某种标准化:

    void foo(File file) {
      file = file.absolute;
      ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    在这种情况下,使用 afinal File file意味着您需要一个单独的局部变量来表示规范化版本,现在代码很容易出错,因为它可能会意外使用原始变量。

  • final因为字段是 API 的重要组成部分。它告诉调用者该字段不会被重新分配;该字段引用的对象始终是同一个对象。final对于局部变量和函数/方法参数,仅影响实现该函数的人。如果实现者不想重新分配变量,他们可以选择不重新分配它。

  • 有些人会声称拥有final局部变量有助于代码的可读性,因为他们知道该变量不会被重新分配。然而,我认为这final可能会产生误导,因为它只说变量不能重新分配,而不是说它不会被改变,并且了解后者更为重要。


1对于重写的方法,参数类型受基类声明的相应参数类型的约束。因此,在重写方法中省略参数类型将使用基类中的参数类型。

  • 我不同意“prefer_final_locals”。将局部变量声明为不可变有什么问题?只有一小部分局部变量被重新赋值,大部分保持不变(值仅被赋值一次)。声明它们是可变的有什么意义? (2认同)