[英]Elegant error handling in Dart like Scala's `Try`
Dart中的数据类:
import 'package:validate/validate.dart';
class AuthUser {
final String email, token, username, bio, image;
AuthUser(this.email, this.token, this.username, this.bio, this.image) {
Validate.isEmail(this.email);
}
@override
String toString() {
return 'AuthUser{email: $email, token: $token, username: $username, bio: $bio, image: $image}';
}
}
如果匹配失败, Validate.isEmail
将引发错误:
static void matchesPattern(String input, RegExp pattern,[String message = DEFAULT_MATCHES_PATTERN_EX]) {
if (pattern.hasMatch(input) == false) {
throw new ArgumentError(message);
}
}
static void isEmail(String input,[String message = DEFAULT_MATCHES_PATTERN_EX]) {
matchesPattern(input,new RegExp(PATTERN_EMAIL),message);
}
现在,我想以一种优雅的方式来上这堂课。 当使用Scala时,我可以使用Try(new AuthUser(...))
并进行模板匹配。
在Dart中,我首先尝试了RxDart,
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
Observable.just(AuthUser("email", "token", "username", "bio", "img"))
.doOnError((e, s) => print("oh no"))
.listen((e) => print(e.toString()));
});
}
不起作用,测试因错误而失败(这意味着RxDart根本不捕获错误!!!)
我想尝试Future,也失败了。
我想使用dartz,但我担心,因为只有一个维护者...
有什么建议吗?
如果可以使用Future
那么此建议有什么问题: 使用Future.sync()包装代码 ? 该代码将如下所示:
void main() {
var f = Future.sync(() {AuthUser("email", "token", "username", "bio", "img"); });
f.then((v) => print("Value: " + v.toString())).catchError((e) => print("Failure: " +e.toString()));
}
主要技巧是Future.sync
有效地启用对参数的惰性求值,但是您必须将参数包装在函数中。 这实际上是Scala编译器为Try
(即按名字调用参数)所做的相同技巧,但需要加上一些括号。
如果仅希望基于是否发生异常返回两种类型的基本功能,则可以轻松创建如下的实用工具类。
否则,我建议@ SergGr的有关使用答案Future.sync
,因为它给你更多的像管道单子。
void main() {
Try<Error, void> result = Try.it(() => Validate.isEmail("test-example.com"));
if (result is Success) {
print("Good");
} else if (result is Failure) {
print("Error: " + result.exception().toString());
}
}
typedef TryExec<V> = V Function();
abstract class Try<E extends Error, V> {
static Try<E, V> it<E extends Error, V>(TryExec<V> fn) {
try {
return Try.success(fn());
} catch (e) {
return Try.failure(e);
}
}
static Try<E, V> failure<E extends Error, V>(Error e) {
return new Failure(e);
}
static Try<E, V> success<E extends Error, V>(V v) {
return new Success(v);
}
}
class Failure<E extends Error, V> extends Try<E, V> {
final E _e;
Failure(this._e);
E exception() => _e;
}
class Success<E extends Error, V> extends Try<E, V> {
final V _v;
Success(this._v);
V value() => _v;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.