我在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);
答案 0 :(得分:3)
是的,你可以result is Future<Map>
。 validate
方法返回的实际值是Future
或不是FutureOr<Map>
。函数的静态类型不会影响该函数,并且由于Future<Map>
不是实际的类,因此您不能拥有“FutureOr”对象。它是真实的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
也就是说,您可以使用其中一种功能类型作为 a 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
或FutureOr
的一个,但是静态类型不说哪一个,所以两者都被认为是错误的分配。
您应该很少有一个声明为返回Future
的非抽象方法。在大多数情况下,最好始终返回Future
或非FutureOr
,并声明方法。然后,如果需要,您可以随时使用该函数作为返回postinstall
,但在您需要的情况下使用更精确的类型。