使用通用回调冻结 class
Freezed class with generic callback
我想定义一个带有通用回调的冻结 class [https://pub.dev/packages/freezed]。
冻结class:
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;
}
使用冻结 class 的小部件:
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;
^
你知道我的代码有什么问题吗?这是冻结的限制吗?您知道解决方法吗?
谢谢!!!
这看起来像是 Dart 类型系统中的一个缺陷。我也鼓励过类似的事情。我不知道一个干净的解决方法。您可以指定的不是直接函数,而是包装到具有“强”方法签名的 class 中的函数。类似的东西应该可以工作:
@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)),
),
);
}
}
我想定义一个带有通用回调的冻结 class [https://pub.dev/packages/freezed]。
冻结class:
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;
}
使用冻结 class 的小部件:
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;
^
你知道我的代码有什么问题吗?这是冻结的限制吗?您知道解决方法吗?
谢谢!!!
这看起来像是 Dart 类型系统中的一个缺陷。我也鼓励过类似的事情。我不知道一个干净的解决方法。您可以指定的不是直接函数,而是包装到具有“强”方法签名的 class 中的函数。类似的东西应该可以工作:
@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)),
),
);
}
}