flutter 如何从 dart (Dartz)的任意类型中轻松提取左或右

6tqwzwtp  于 2023-01-14  发布在  Flutter
关注(0)|答案(8)|浏览(242)

我希望从返回Either<Exception, Object>类型的方法中轻松提取值。
我正在做一些测试,但无法轻松测试我的方法的返回。

例如:

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.
qv7cva1a

qv7cva1a1#

好了,这里的解决方案我的问题:

提取/检索数据

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>()));
ddhy6vgd

ddhy6vgd2#

朋友们,
只需像下面这样创建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
  }
}
cnh2zyt3

cnh2zyt33#

我不能发表评论...但也许你可以看看这个post。它不是同一种语言,但看起来像是同一种行为。
祝你好运。

j9per5c4

j9per5c44#

提取值的另一种方法是简单地转换为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();
  }
}
6bc51xsx

6bc51xsx5#

向左或向右提取:
左侧:

print(result.fold((l) => l, (r) => null))

右:

print(result.fold((l) => null, (r) => r))
xdyibdwo

xdyibdwo6#

我返回任一类型的折叠结果

@override
  Future<Either<Failure, bool>> call(UpdateReceiptParams params) async {
    Either<Failure, ProcurementStore> procurementStore =
        await _getProcurementStore();
    return procurementStore.fold((_) => Left(ServerFailure()),
        (procurementlStore) async {
      List<ReceiptItem> receiptItems =
          _getReceiptItem(params.shipmentStatus, params.quantityAmounts);
      final Receipt receipt = Receiplt(
          procurementStore: procurementStore,
          costCenter: const CostCenter(),
          receiptItems: receiptItems,
          shipmentId: params.shipmentStatus.Id,
          receiptType: params.shipmentStatus.ShipmentType,
          description: params.description,
          operationPeriodId: 0,
          receiptDate: params.date,
          receiptTime: params.time);
      return await shipmentsRepository.updateReceipt(receipt);
    });
  }
bd1hkmkf

bd1hkmkf7#

使用Either给出的fold方法,并将不想为null的部分Map到自身:

extension EitherExtension<L, R> on Either<L, R> {
  R? getRight() => fold<R?>((_) => null, (r) => r);
  L? getLeft() => fold<L?>((l) => l, (_) => null);
}

然后导入包含此扩展名的文件,您可以在任一示例上调用.getRight()或.getLeft()。

polkgigr

polkgigr8#

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);
  },
);

}

相关问题