【问题标题】:Freezed class with generic callback具有通用回调的冻结类
【发布时间】:2021-01-29 12:29:14
【问题描述】:

我想定义一个带有通用回调的冻结类 [https://pub.dev/packages/freezed]。

冻结类:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'foo.freezed.dart';

@freezed
abstract class Foo<T> with _$Foo {
  factory Foo({
    // String Function() callBackOne,
    String Function(T) callBackTwo,
  }) = _Foo;
}

使用 Freezed 类的小部件:

class MyHomePage extends StatelessWidget {
  // final fooOne = Foo<int>(callBackOne: () => 'Result: 42');
  final fooTwo = Foo<int>(callBackTwo: (value) => 'Result: ${value * 3}');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(fooTwo.callBackTwo(14)),
      ),
    );
  }
}

错误:

lib/foo.freezed.dart:128:26: Error: The return type of the method '_Foo.callBackTwo' is 'String Function(T)', which does not match the return type, 'String Function(dynamic)', of the overridden method, '_$Foo.callBackTwo'.
Change to a subtype of 'String Function(dynamic)'.
  String Function(T) get callBackTwo;
                         ^
lib/foo.freezed.dart:31:26: Context: This is the overridden method ('callBackTwo').
  String Function(T) get callBackTwo;

                         ^

你知道我的代码有什么问题吗?是冻结的限制吗?你知道解决方法吗?

谢谢!!!

【问题讨论】:

    标签: flutter dart generics freezed


    【解决方案1】:

    这看起来像是 Dart 类型系统中的一个缺陷。我也鼓励过类似的事情。我不知道一个干净的解决方法。您可以指定的不是直接函数,而是包装到具有“强”方法签名的类中的函数。类似的东西应该可以工作:

    @freezed
    abstract class Foo<T> with _$Foo {
      factory Foo({
        Func<T> callBackTwo,
      }) = _Foo;
    }
    
    class Func<T> {
      final String Function(T) _apply;
    
      Func(this._apply) : assert(_apply != null);
    
      String call(T value) {
        return _apply(value);
      }
    }
    
    class MyHomePage extends StatelessWidget {    
      final fooTwo = Foo<int>(Func<int>((value) => 'Result: ${value * 3}'));
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text(fooTwo.callBackTwo(14)),
          ),
        );
      }
    }
    

    这不太好,因为你要输入更多。但我们可以尽量减少打字:

    @freezed
    abstract class Foo<T> with _$Foo {
      factory Foo({
        Func<T> callBackTwo,
      }) = _Foo;
    
      factory Foo.from(String Function(T) arg) {
        return Foo<T>(callBackTwo: Func<T>(arg));
      }
    }
    
    class MyHomePage extends StatelessWidget {    
      final fooTwo = Foo<int>.from((value) => 'Result: ${value * 3}');
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text(fooTwo.callBackTwo(14)),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      • 2014-09-14
      • 2023-01-18
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多