如何从 Dart (Dartz) 中的 Either 类型中轻松提取 Left 或 Right
How to extract Left or Right easily from Either type in Dart (Dartz)
我希望从 return 类型 Either<Exception, Object>
的方法中轻松提取值。
我正在做一些测试,但无法轻松测试我的方法 return。
例如:
final Either<ServerException, TokenModel> result = await repository.getToken(...);
为了测试我能做到这一点
expect(result, equals(Right(tokenModelExpected))); // => OK
现在如何直接检索结果?
final TokenModel modelRetrieved = Left(result); ==> Not working..
我发现我必须这样投:
final TokenModel modelRetrieved = (result as Left).value; ==> But I have some linter complain, that telling me that I shouldn't do as to cast on object...
我也想测试异常,但它不起作用,例如:
expect(result, equals(Left(ServerException()))); // => KO
所以我尝试了这个
expect(Left(ServerException()), equals(Left(ServerException()))); // => KO as well, because it says that the instances are different.
我无法 post 发表评论...但也许您可以看看这个 post。这不是同一种语言,但看起来是相同的行为。
祝你好运。
好的,这里是我的问题的解决方案:
到extract/retrieve数据
final Either<ServerException, TokenModel> result = await repository.getToken(...);
result.fold(
(exception) => DoWhatYouWantWithException,
(tokenModel) => DoWhatYouWantWithModel
);
//Other way to 'extract' the data
if (result.isRight()) {
final TokenModel tokenModel = result.getOrElse(null);
}
测试异常
//You can extract it from below, or test it directly with the type
expect(() => result, throwsA(isInstanceOf<ServerException>()));
Future<Either<Failure, FactsBase>> call(Params params) async {
final resulting = await repository.facts();
return resulting.fold(
(failure) {
return Left(failure);
},
(factsbase) {
DateTime cfend = sl<EndDateSetting>().finish;
List<CashAction> actions = factsbase.transfers.process(facts: factsbase, startDate: repository.today, finishDate: cfend); // process all the transfers in one line using extensions
actions.addAll(factsbase.transactions.process(facts: factsbase, startDate: repository.today, finishDate: cfend));
for(var action in actions) action.account.cashActions.add(action); // copy all the CashActions to the Account.
for(var account in factsbase.accounts) account.process(start: repository.today);
return Right(factsbase);
},
);
}
提取值的另一种方法是简单地转换为 Option
,然后转换为 dart
可为空:
final Either<Exception, String> myEither = Right("value");
final String? myValue = myEither.toOption().toNullable();
如果你愿意,你可以定义一个简单的扩展来简化这个:
extension EitherHelpers<L, R> on Either<L, R> {
R? unwrapRight() {
return toOption().toNullable();
}
}
朋友,
像这样创建dartz_x.dart。
import 'package:dartz/dartz.dart';
extension EitherX<L, R> on Either<L, R> {
R asRight() => (this as Right).value; //
L asLeft() => (this as Left).value;
}
然后像那样使用。
import 'dartz_x.dart';
void foo(Either<Error, String> either) {
if (either.isLeft()) {
final Error error = either.asLeft();
// some code
} else {
final String text = either.asRight();
// some code
}
}
extension EitherExtension<L, R> on Either<L, R> {
R? getRight() => fold<R?>((_) => null, (r) => r);
L? getLeft() => fold<L?>((l) => l, (_) => null);
}
我希望从 return 类型 Either<Exception, Object>
的方法中轻松提取值。
我正在做一些测试,但无法轻松测试我的方法 return。
例如:
final Either<ServerException, TokenModel> result = await repository.getToken(...);
为了测试我能做到这一点
expect(result, equals(Right(tokenModelExpected))); // => OK
现在如何直接检索结果?
final TokenModel modelRetrieved = Left(result); ==> Not working..
我发现我必须这样投:
final TokenModel modelRetrieved = (result as Left).value; ==> But I have some linter complain, that telling me that I shouldn't do as to cast on object...
我也想测试异常,但它不起作用,例如:
expect(result, equals(Left(ServerException()))); // => KO
所以我尝试了这个
expect(Left(ServerException()), equals(Left(ServerException()))); // => KO as well, because it says that the instances are different.
我无法 post 发表评论...但也许您可以看看这个 post。这不是同一种语言,但看起来是相同的行为。
祝你好运。
好的,这里是我的问题的解决方案:
到extract/retrieve数据
final Either<ServerException, TokenModel> result = await repository.getToken(...);
result.fold(
(exception) => DoWhatYouWantWithException,
(tokenModel) => DoWhatYouWantWithModel
);
//Other way to 'extract' the data
if (result.isRight()) {
final TokenModel tokenModel = result.getOrElse(null);
}
测试异常
//You can extract it from below, or test it directly with the type
expect(() => result, throwsA(isInstanceOf<ServerException>()));
Future<Either<Failure, FactsBase>> call(Params params) async {
final resulting = await repository.facts();
return resulting.fold(
(failure) {
return Left(failure);
},
(factsbase) {
DateTime cfend = sl<EndDateSetting>().finish;
List<CashAction> actions = factsbase.transfers.process(facts: factsbase, startDate: repository.today, finishDate: cfend); // process all the transfers in one line using extensions
actions.addAll(factsbase.transactions.process(facts: factsbase, startDate: repository.today, finishDate: cfend));
for(var action in actions) action.account.cashActions.add(action); // copy all the CashActions to the Account.
for(var account in factsbase.accounts) account.process(start: repository.today);
return Right(factsbase);
},
);
}
提取值的另一种方法是简单地转换为 Option
,然后转换为 dart
可为空:
final Either<Exception, String> myEither = Right("value");
final String? myValue = myEither.toOption().toNullable();
如果你愿意,你可以定义一个简单的扩展来简化这个:
extension EitherHelpers<L, R> on Either<L, R> {
R? unwrapRight() {
return toOption().toNullable();
}
}
朋友,
像这样创建dartz_x.dart。
import 'package:dartz/dartz.dart';
extension EitherX<L, R> on Either<L, R> {
R asRight() => (this as Right).value; //
L asLeft() => (this as Left).value;
}
然后像那样使用。
import 'dartz_x.dart';
void foo(Either<Error, String> either) {
if (either.isLeft()) {
final Error error = either.asLeft();
// some code
} else {
final String text = either.asRight();
// some code
}
}
extension EitherExtension<L, R> on Either<L, R> {
R? getRight() => fold<R?>((_) => null, (r) => r);
L? getLeft() => fold<L?>((l) => l, (_) => null);
}