Dart:如何使用类作为switch case?

3

大家好,希望你们一切都好!

我有一个问题,就是如何在一个类上使用switch case语句? (这里“state”是主类,其他类都从state类继承而来。)

举个例子,我试图将这个代码替换:

if(state is LoadingPage)        {return LoadingPage;}
else if {state is SuccessPage)  {return SuccessPage;}
else if {state is FailPage)     {return FailPage;}

转换为:

switch (state){
case LoadingPage:   {return LoadingPage;}
case SuccessPage:   {return SuccessPage;}
case FailPage:      {return FailPage;}
}

它没有起作用,对我有用的是将状态作为字符串进行处理,就像这样:

switch (state.toString()){
    case 'LoadingPage':      {return LoadingPage;}
    case 'SuccessPage':      {return SuccessPage;}
    case 'FailPage':         {return FailPage;}
    }

虽然它可以运行,但这只是一种临时解决方案。比如我要编辑某些内容,由于它是一个字符串,所以修改起来会非常困难。


嗨,我已经添加了一个类似于 switch 的解决方案。你可以使用 map 来处理所有情况,或者使用 maybeMap() 来仅处理你需要的情况。 - Ariel
4个回答

0
做这个:
switch (state.runtimeType){
case LoadingPage:   {return LoadingPage;}
case SuccessPage:   {return SuccessPage;}
case FailPage:      {return FailPage;}
}

不应该使用runtimeType,它会根据编译器选项而改变。而且它在子类和泛型中的工作效果不佳。 https://github.com/felangel/bloc/issues/1595 - DaveVentura

0

有一个名为freezed的软件包,可以用于此精确解决方案。我们不使用switch,而是使用map和/或maybeMap

@freezed
class MemberState with _$MemberState {
  factory MemberState.initial() = _MemberStateInitial;
  factory MemberState.loading() = _MemberStateLoading;
  factory MemberState.loadSuccess({required MemberDetail detail}) =
      _MemberStateLoadSuccess;
  factory MemberState.loadFailure({required AppFailure failure}) =
      _MemberStateLoadFailure;
}

使用方法:

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<MemberBloc, MemberState>(
      builder: (context, state) {
        return const Scaffold(
          body: state.map(
              initial: initial,
              loading: loading,
              loadSuccess: loadSuccess,
              loadFailure: loadFailure),
        );
      },
    );
  }

当然,我将它与BLoCs一起使用,但基本概念是相同的。您可以按照任何您喜欢的方式使用它。而且,最好的事情是它全部自动生成。因此,您不必自己编写代码。


0

你正在寻找switch表达式。Dart团队在Dart的V3版本中刚刚添加了这个功能。

enum PageState { LoadingPage, SuccessPage, FailPage }

void main() {
  final state = PageState.SuccessPage;
  final text = switch (state) {
    PageState.LoadingPage => 'LoadingPage',
    PageState.SuccessPage => 'SuccessPage',
    PageState.FailPage => 'FailPage',
    _ => 'None'
  };
  print(text);
}

更多细节,请阅读这里


0
2023年 - 使用Dart 3.0模式匹配的switch 代码概述
class Dog {
  Dog({required this.name});
  final String name;
}

class Cat {
  Cat({required this.name});
  final String name;
}

String checkType(dynamic v) {
  String type;

  switch (v) {
    case Dog(:final name):
      type = 'dog, $name';
    case Cat cat:
      type = 'cat, ${cat.name}';
    case int:
      type = 'int';
    case (String name, String age):
      type = 'Record ($name, $age)';
    case {'user': {'name': final String name, 'age': final int age}}:
      type = 'User Json $name, $age';
    default:
      type = 'unknown';
  }

  return type;
}

对象解构

switch (v) {
  case Dog(name:final name):

// or You can skip name if use same name.

switch (v) {
  case Dog(:final name):


⚠️ 文档:如果值的类型不同,则将其驳斥。
你应该使用正确的类型来解构对象。
只需使用finalvar来指示数据类型,以便始终使用相同类型的对象字段。
return switch (v) {
  Dog(:String age) => 'dog, $age', // Compile error 'The getter 'age' isn't defined for the type 'Dog'.'
  Dog(name: String otherName) => 'dog, $otherName', // OK, Success to match
  Dog(:int name) => 'dog, $name', // Fail to match
  Dog(:String name) => 'dog, $name', // Success to match, But can't to be reached.

只需将其分配给变量(可以使用前缀final来声明为常量)。
case Cat cat:
  type = 'cat, ${cat.name}';

or

case final Cat cat:
  type = 'cat, ${cat.name}';

记录销毁

case (String name, String age):
  type = 'Record ($name, $age)';

地图破坏
case {'user': {'name': final String name, 'age': final int age}}:
  type = 'User Json $name, $age';

你还可以使用switch表达式。
String checkType(dynamic v) {
  return switch (v) {
    Dog(:final name) => 'dog, $name',
    Cat cat => 'cat, ${cat.name}',
    int => 'int',
    (String name, String age) => 'Record ($name, $age)',
    {'user': {'name': final String name, 'age': final int age}} =>
      'User Json $name, $age',
    _ => 'unknown',
  };
}

你可以在Dart文档中查看更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接