Can I use 'is' operator in a switch case in Dart?
Asked Answered
A

3

12

I feel like this is a stupid question, but I cant get it to work.

What I have:

if (current is classA){
   //do stuff
   return;
}
if (current is classB){
   //do stuff
   return;
}
if (current is classC){
   //do stuff
   return;
}

What I want:

switch (currentState) {
   case is classA: { 
      //do stuff
      break;
   }
   case is classB: { 
      //do stuff
      break;
   }
   case is classC: { 
      //do stuff
      break;
   }
}

What I really want (Kotlin):

When (currentState){
   is classA -> //do stuff
   is classB -> //do stuff
   is classC -> //do stuff
}

Is there anyway I can use the Dart Switch like the Kotlins When operator, or at least use other operators then == to assert the case evaluations?

Adara answered 28/2, 2019 at 16:45 Comment(0)
S
10

Edit: Yes, now you can. Dart 3.0 introduced pattern matching, so now you can write:

switch (currentState) {
  case classA():
      //do stuff
  case classB():
      //do stuff
  case classC():
      //do stuff
}

You can also do much more, read about it here: https://dart.dev/language/patterns

The historical answer was:

No.

The Dart switch case is a very low-level construct. It allows only constant-value expressions that don't override operator == (except for a few basic platform types), so effectively it can be implemented using identical checks.

There is no ability to do complicated checks, or checks on the type of the object, only identity checks.

The recommended pretty way to do what you want is to have ClassA, > ClassB and ClassC all implement an interface with a doStuff member, and then do:

currentState.doStuff()

If that is not possible, you are back to the if sequence.

Sombrous answered 1/3, 2019 at 10:3 Comment(3)
Ok, I'm using BLoC pattern in flutter and have to check witch State is being received. Each state extends MyBlocState and determine what Widget-tree to build. Judging by your answer there is no way to use a switch statement in this case. Thanks for the answer and please correct me if I interpreted it wrong.Principle
Same boat as Joel, this sucks :(Meakem
No longer the case. https://mcmap.net/q/921029/-can-i-use-39-is-39-operator-in-a-switch-case-in-dartHugibert
E
6
switch (runtimeType) {
   case ClassA: //do stuff 
      return;
   case ClassB: //do stuff
      return;
}
Embraceor answered 23/6, 2022 at 9:30 Comment(4)
it's the most helpful answer switch (state.runtimeType) { ... }Agnostic
While this is one way to do it, note that the static analyzer won't be able to infer the more specific type like it can do with if (x is X) statements, meaning you might have to use as in the case clauses. In that case, if statements might be cleaner and less verboseRefection
wrong, cause steel your have to cast your subtypes manuly, it's not like kotlin. steel you have to type (ClassA as SubtypeTarget).doSomthing(); or ...Fields
Doesn't work for types like int?.Tantalizing
R
5

You can't use the same syntax as in Kotlin but you can use Freezed.

https://pub.dev/packages/freezed

It allows you to use a similar syntax.

Considering this model:

@freezed
abstract class Model with _$Model {
  factory Model.first(String a) = First;
  factory Model.second(int b, bool c) = Second;
}

You can use when in the following way:

var model = Model.first('42');

print(
  model.when(
    first: (String a) => 'first $a',
    second: (int b, bool c) => 'second $b $c'
  ),
); // first 42
Resect answered 9/4, 2020 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.