我有一个扩展方法:
extension When<T extends Object> on T {
T? when(bool Function(T self) predicate, {T Function(T self)? otherwise}) {
if (predicate(this)) return this;
return otherwise?.call(this);
}
}
它允许我在测试后对内部变量和内部函数结果进行一些处理,而无需将它们保存在变量中。
有时,当我想将它与Widgets一起使用时,我很烦恼,我总是需要将它转换为Widget。所以,我去做了以下扩展,因为它更具体,编译器使用它而不是第一个。
extension WhenWidget<T extends Widget> on T {
Widget? when(bool Function(T self) predicate, {Widget Function(T self)? otherwise,}) {
if (predicate(this)) return this;
return otherwise?.call(this);
}
}
我问自己,那我可以做这样的事情吗?
extension When<R extends Object, T extends R> on T {
R? when(bool Function(T self) predicate, {R Function(T self)? otherwise}) {
if (predicate(this)) return this;
return otherwise?.call(this);
}
}
但是这样一来,我所有的类型推断都消失了。我想做的是以一种知道如何处理超类型的方式创建这个扩展。所以,如果我尝试做:
final variable = 1.when((self) self.isEven, otherwise: (self) => self + 0.5)!;
variable
将是 num
而不是 Object
.
您可以使用扩展
T
并将 R
约束为 R
的子类型的类型参数,创建一个同时适用于原始类型 T
及其任何超类型 R
的扩展方法。这是扩展方法的示例实现:
extension When<R, T extends R> on T {
R? when<R>(bool Function(T self) predicate, {R Function(T self)? otherwise}) {
if (predicate(this)) return this as R;
return otherwise?.call(this);
}
}
在此实现中,
R
是表示预期返回类型的类型参数,T
是表示调用扩展方法的对象类型的类型参数。 T extends R
约束确保 T
是 R
的子类型,因此您可以返回 T
或其任何超类型作为 when
方法的结果。
使用此扩展方法,您可以在类型为
when
或其任何超类型T
的任何对象上调用R
方法,返回类型将根据otherwise
回调的类型推断。例如,你可以这样做:
final variable = 1.when((self) => self.isEven, otherwise: (self) => self + 0.5)!;
在这种情况下,
variable
的值将是double
。