我正在尝试创建一个Dart函数,该函数实质上是使用一些样板错误处理代码来包装其他函数,否则返回由原始函数返回的值。一个关键要求是它应该接受具有多个不同返回类型的函数,同时避免在多个不同函数之间重复通用错误处理逻辑。我发现一种方法似乎可以通过使用动态类型来工作,除了编译器无法检测类型不匹配之外,因此只能在运行时捕获它们。
有没有更好的方法来实现我的目标,特别是在编译时捕获类型不匹配的方法?
下面是我的代码的简化示例,其中的函数可以很好地编译,但是在运行时getAString会引发错误Dart Error: Unhandled exception: type 'List<String>' is not a subtype of type 'String'
/// API函数调用的签名
typedef APIFunctionCall =动态Function();
dynamic doWithErrorHandling(APIFunctionCall fn, {retries: 2}) async {
for (int attempts = 0; attempts < retries + 1; attempts++) {
try {
return await fn();
}
on Exception catch (e) {
print(
"This is just an example; actual function does a bunch of more specific error handling.");
}
}
}
Future<String> getAString() async {
// Want a function that can support multiple return types but detect type errors
String doesReturnAString = await doWithErrorHandling(() async => 'hello world'); // This runs fine
String doesntReturnAString = await doWithErrorHandling(() async => <String>['hello', 'world']); // This throws an Error
return doesntReturnAString;
}
最佳答案
您可以使用类型参数抽象返回类型:
Future<T> doWithErrorHandling<T>(Future<T> fn(), {int retries = 2}) async {
do {
try {
return await fn();
} catch (e) {
// record error.
}
retries--;
} while (retries >= 0);
return null; // or whatever.
}
这样,您可以使用任何函数进行调用。在大多数情况下,可以从参数函数的静态类型或周围环境期望的类型中推断出类型参数,但如果不是,则可以自己编写。
Future<String> getAString() async {
String doesReturnAString = await doWithErrorHandling(() async => 'hello world');
// The next line has a compile-time type error!
String doesntReturnAString = await doWithErrorHandling(() async => <String>['hello', 'world']);
return doesntReturnAString;
}
(作为不相关的提示,您永远不要捕获
Exception
。Dart错误不实现Exception
,它们实现Error
。Exception
是用户打算捕获并处理的某些抛出对象使用的毫无意义的标记接口(interface),但是在这种情况下,您可以应该捕获特定的异常,例如on FormatException
,而不是普通的Exception
。因此,一般规则:切勿编写on Exception
)。关于dart - Dart:函数的类型安全性,该函数将具有变化的返回值的函数作为参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53056704/