Dart 中的通用参数类型?

Generic parameter type in Dart?

我正在尝试创建一个 class,它使用泛型类型作为回调中的参数,return 是 Fl​​utter 的 Widget 的某些子类型。这是我的开头:

    class Subscriber<P extends PublishingController> extends StatefulWidget {
      const Subscriber({required this.builder, Key? key}) : super(key: key);

      final Widget Function(P) builder;

      @override
      _SubscriberState<P> createState() => _SubscriberState<P>();
    }

    class _SubscriberState<P extends PublishingController> extends State<Subscriber> {
      final P publisher = GetIt.instance.get<P>();

      @override
      void initState() {
        publisher.subscribe(rebuild);
        super.initState();
      }

      @override
      Widget build(BuildContext context) {
        return widget.builder(publisher);
      }

      @override
      void dispose() {
        publisher.unsubscribe(rebuild);
        super.dispose();
      }

      void rebuild() {
        setState(() {});
      }
    }

...与发布者:

    mixin Publisher {
      List<Function> subscribers = <void Function()>[];

      void subscribe(Function f) {
          subscribers.add(f);
      }

      void unsubscribe(Function f) {
        subscribers.remove(f);
      }

      void publish() {
        for (var f in subscribers) {
          f();
        }
      }
    }

    class PublishingController with Publisher {}

...以及我如何称呼它:

  child: Subscriber<MapController>(
             builder: (controller) => Column(...

...与:

  class MapController extends PublishingController {...

...但这给了我错误:

  ======== Exception caught by widgets library =======================================================
  The following _TypeError was thrown building Subscriber<MapController>(dirty, state: _SubscriberState<MapController>#d7e05):
  type '(MapController) => Column' is not a subtype of type '(PublishingController) => Widget'

我想我正在通过泛型指定参数类型,并且函数可以 return 其 return 类型的子类型——我在这里弄错了什么?

编辑:

我让它工作了,但我没有把它作为答案——我不明白问题出在哪里,或者为什么这个版本能工作;我将订阅者 class 更改为:

    abstract class Builder<P extends PublishingController> extends StatefulWidget {
      const Builder({required this.builder, Key? key}) : super(key: key);
      final Widget Function(P) builder;
    }

    class Subscriber<P extends PublishingController> extends Builder<P> {
      const Subscriber({required builder, Key? key}) : super(builder: builder, key: key);

      @override
      _SubscriberState<P> createState() => _SubscriberState<P>();
    }

如果有人想解释为什么这个改变会有所不同,请把它放在一个答案中,我很乐意接受。

您的 _SubscriberState<P> class 扩展 State<Subscriber>,在您的情况下是 shorthand for State<Subscriber<PublishingController>> 而不是 State<Subscriber<P>>.

_SubscriberState<P> 继承的 widget 成员的静态类型因此将为 Subscriber<PublishingController>,而 widget.builder 的静态类型将为 Widget Function(PublishingController) .在运行时,关联的 Subscriber 对象引用了 Column Function(MapController) 对象。但是,这不能被视为 Widget Function(PublishingController),因为它不接受所有 PublishingController 参数,因此您最终会遇到运行时错误。

参见: