我有一個有回呼的泛型StatefulWidget類。Function當我嘗試呼叫該回呼時,我得到一個運行時TypeError:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following _TypeError was thrown building MyStatefulWidget<int>(dirty, state:
MyState<int>#cacb3):
type '(int) => Widget' is not a subtype of type '(dynamic) => Widget'
The relevant error-causing widget was:
MyStatefulWidget<int>
MyStatefulWidget:file:///path/to/my_flutter_project/lib/main.dart:11:13
When the exception was thrown, this was the stack:
#0 MyState.build (package:my_flutter_project/main.dart:33:19)
可重現的例子:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
Widget f(int n) => Text('$n');
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyStatefulWidget<int>(callback: foo, value: 42),
);
}
}
class MyStatefulWidget<T> extends StatefulWidget {
final Widget Function(T) callback;
final T value;
const MyStatefulWidget({
required this.callback,
required this.value,
Key? key,
}) : super(key: key);
@override
MyState<T> createState() => MyState<T>();
}
class MyState<T> extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return widget.callback(widget.value);
}
}
我試過明確地構造MyStatefulWidgetas MyStatefulWidget<int>,但這沒有幫助。Widget Function(dynamic)型別來自哪里?
uj5u.com熱心網友回復:
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)。在運行時,關聯MyStatefulWidget物件具有對f(a的參考。但是,由于不能接受所有引數,因此Widget Function(int)不能將其視為Widget Function(dynamic)(如預期的那樣MyState<T>) ,因此在運行時您最終會得到 a 。fdynamicTypeError
底線
如果你有一個 generic StatefulWidget,你必須在StatefulWidget參考它的State類或State參考它的類的任何地方顯式且一致地提供型別引數StatefulWidget。常見的錯誤是:
- 忽略型別引數
createState。 - 為相應
State類宣告繼承時忽略型別引數。
所以:
class MyStatefulWidget<T> extends StatefulWidget {
...
MyState createState() => MyState(); // WRONG
}
class MyState<T> extends State<MyStatefulWidget> { // WRONG
...
}
相反應該是:
class MyStatefulWidget<T> extends StatefulWidget {
...
MyState<T> createState() => MyState<T>();
}
class MyState<T> extends State<MyStatefulWidget<T>>
...
}
分析strict_raw_types選項有時可以幫助捕捉此類錯誤,盡管當前的實作似乎只檢查隱式dynamic型別引數并且似乎沒有捕捉到型別引數受到限制的情況(例如,如果你有MyStatefulWidget<T extends num>)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/460177.html
