一个常见的问题,特别是从Dart 2开始,是是否有可能要求某些或所有类型的某些或所有通用类型参数-例如List<int>
而不是{{1 }}或List
而不是MyType<Foo>
。
并不一定总是清楚意图是什么-即,这是样式问题(您/您的团队喜欢看类型),是为了防止错误(忽略类型参数似乎会导致更多错误)您/您的团队的错误)或合同规定的问题(您的库期望是类型参数)
。例如,用户在dart-misc
上写道:
基本上,如果我有这个:
MyType
我没有指定类型:
abstract class Mixin<T> {}
有没有办法让第二个不被允许?
答案 0 :(得分:5)
严格来说,是的,和不是。
如果您想强制在自己的项目中始终使用类型变量(而不是类型推断或默认值),可以使用 optional {{3 }}。请注意,在很多情况下,该规则违反了Dart样式指南的官方建议linter rules such as always_specify_types
。
如果您要强制始终使用泛型类型参数,而 时,默认参数将令人困惑-例如// Works class Cls extends Object with Mixin<int> {} // ...also works
class Cls extends Object with Mixin {}
隐含含义List
,还还不存在这样的棉绒-尽管我们计划将其添加为分析器的{em> mode :AVOID redundant type arguments on generic invocations
。
以上两项建议都将对您自己有所帮助,但是,如果您要创建供其他人使用的库,则可能会询问是否可以要求< / em>使用您的类的类型参数。例如,从上方:
List<dynamic>
您可以做的第一件事是向abstract class Mixin<T> {}
abstract class Class extends Object with Mixin {}
添加默认边界:
T
如果您想允许任何内容,但又想在// If T is omitted/not inferred, it defaults to num, not dynamic.
abstract class Mixin<T extends num> {}
动态时难以使用类/混合,则可以选择其他默认界限,例如{{1} },甚至更好的https://github.com/dart-lang/sdk/issues/33119:
在实践中,我用
T
来表示“任何我不在乎的元素”
Object
(您也可以为此使用void
)
如果这是一个受您控制的类,则可以添加一个 asserttion ,以防止以您不支持或不期望的方式使用该类。例如:
abstract class Mixin<T extends void> {
T value;
}
class Class extends Mixin {}
void main() {
var c = Class();
// Compile-time error: 'oops' isn't defined for the class 'void'.
c.value.oops();
}
最后,您可以编写一个自定义的lint或工具来禁止遗漏某些泛型类型参数,但这可能是最繁重的工作,并且如果以前的任何方法对您有用,我强烈建议您使用!