我在AngularDart中有一个如下的类:
abstract class Validator {
Map validate(AbstractControl c);
}
仔细观察,这曾经是(在我们添加强模式支持之前):
abstract class Validator {
validate(AbstractControl c);
}
它在技术上支持返回Future或Map的问题。
我想重构它并使用
FutureOr
正确键入它:abstract class Validator {
FutureOr<T> validate(AbstractControl c);
}
我可以在运行时使用
is
检查吗? (在DDC和dart2js中)void runValidator(Validator v) {
var result = v.validate(...);
if (result is Future) {
// async...
} else {
// sync...
}
}
我是否在正确地考虑这一点?
编辑:如下所述,我的意思是
if (result is Future<T>) {
} else if (result is T) {
}
还有一个问题,
validate
是否与这两个typedef
相匹配:Future<Map> AsyncValidate(AbstractControl c);
Map SyncValidate(AbstractControl c);
最佳答案
是的,您可以执行result is Future<Map>
。 validate
方法返回的实际值是Future
或不是。该函数的静态类型不会对此产生影响,并且由于FutureOr<Map>
不是实际的类,因此不能有一个对象为“FutureOr”。它可以是真实的Future<Map>
或Map
。
对于第二个问题,这取决于“匹配”的含义。
您可以使用返回Map
或FutureMap
的方法覆盖该方法:
abstract class Validator {
FutureOr<Map> validate(abstractControl c);
}
class AsyncValidator extends Validator {
Future<Map> validate(AbstractControl c) {...}
}
class SyncValidator extends Validator {
Map validate(AbstractControl c) {...}
}
也就是说,您可以使用提到的一种函数类型作为
Validator.validate
,而不能在另一方向使用。typedef FutureOr<Map> Validate(AbstractControl c);
typedef Future<Map> AsyncValidate(AbstractControl c);
typedef Map SyncValidate(AbstractControl c);
Validator v = ...;
Validate f0 = v.validate; // Safe.
AsyncValidate f1 = v.validate; // BAD assignment.
SyncValidate f2 = v.validate; // BAD assignment.
Map syncValidate(AbstractControl c) { ... }
Future<Map> asyncValidate(AbstractControl c) { ... }
v = syncValidate; // Good assignment.
v = asyncValidate; // Good assignment.
实际上,验证器
validate
的具体v
方法可能可以分配给f1
或f2
之一,但其静态类型没有说明哪一个,因此都被认为是错误的分配。您应该很少有声明为return
FutureOr
的非抽象方法。在大多数情况下,最好总是返回Future
或non-Future
,并这样声明方法。然后,您始终可以根据需要使用该函数作为返回的FutureOr
,但在需要时使用更精确的类型。关于dart - FutureOr <T>是否具有化身为Future <T>/<T>的类型?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42098554/