我有一个通用StatefulWidget类,它有一个Function回调的通用类。当我尝试调用该回调时,我得到一个运行时TypeError:
\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following _TypeError was thrown building MyStatefulWidget<int>(dirty, state:\nMyState<int>#cacb3):\ntype \'(int) => Widget\' is not a subtype of type \'(dynamic) => Widget\'\n\nThe relevant error-causing widget was:\n MyStatefulWidget<int>\n MyStatefulWidget:file:///path/to/my_flutter_project/lib/main.dart:11:13\n\nWhen the exception was thrown, this was the stack:\n#0 MyState.build (package:my_flutter_project/main.dart:33:19)\nRun Code Online (Sandbox Code Playgroud)\n可重现的例子:
\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following _TypeError was thrown building MyStatefulWidget<int>(dirty, state:\nMyState<int>#cacb3):\ntype \'(int) => Widget\' is not a subtype of type \'(dynamic) => Widget\'\n\nThe relevant error-causing widget was:\n MyStatefulWidget<int>\n MyStatefulWidget:file:///path/to/my_flutter_project/lib/main.dart:11:13\n\nWhen the exception was thrown, this was the stack:\n#0 MyState.build (package:my_flutter_project/main.dart:33:19)\nRun Code Online (Sandbox Code Playgroud)\n我已经尝试显式构造MyStatefulWidget为MyStatefulWidget<int>,但这没有帮助。哪儿是Widget Function(dynamic)?
MyState createState() => MyState();省略类型参数,因此它返回 a MyState,它是 的简写MyState<dynamic>。
此外,MyState<T> extends State<MyStatefulWidget>是 的简写... extends State<MyStatefulWidget<dynamic>>,而不是预期... extends State<MyStatefulWidget<T>>的 。
MyState<T>因此,的继承成员的静态类型widget将是MyStatefulWidget<dynamic>, 的静态类型widget.callback将是Widget Function(dynamic)。在运行时,关联的对象具有对(a 的MyStatefulWidget引用。但是,不能将其视为(如 所期望的那样),因为不能接受所有参数,因此您最终会在运行时得到 a 。fWidget Function(int)Widget Function(dynamic)MyState<T>fdynamicTypeError
如果您有泛型StatefulWidget,则必须在StatefulWidget引用其State类或State引用其StatefulWidget类的所有位置显式且一致地提供类型参数。常见错误有:
createState.State类的继承时忽略类型参数。所以:
class MyStatefulWidget<T> extends StatefulWidget {
...
MyState createState() => MyState(); // WRONG
}
class MyState<T> extends State<MyStatefulWidget> { // WRONG
...
}
Run Code Online (Sandbox Code Playgroud)
相反应该是:
class MyStatefulWidget<T> extends StatefulWidget {
...
MyState<T> createState() => MyState<T>();
}
class MyState<T> extends State<MyStatefulWidget<T>>
...
}
Run Code Online (Sandbox Code Playgroud)
分析strict_raw_types选项有时可以帮助捕获此类错误,尽管当前的实现似乎仅检查隐式dynamic类型参数,并且似乎无法捕获类型参数受到限制的情况(例如,如果您有MyStatefulWidget<T extends num>)。