93

I am trying to understand how the switch is working in the dart. I have very simple code:

methodname(num radians) {
  switch (radians) {
    case 0:
      // do something
      break;
    case PI:
      // do something else
      break;
  }
}

This unfortunately does not work. If left like this the error is: case expressions must have the same type (I think the type is num, but not the editor). If I change 0 to 0.0 it says: The switch type expression double cannot override == operator - I have no idea what this means!

So what is the way to do this switch case? I can turn it onto if/else probably but I wanted to know how to make the switch work and why is it not working in the first place.

I am running the latest stable version of DartEditor.

marli
  • 529
  • 10
  • 19
Peter StJ
  • 2,297
  • 3
  • 21
  • 29
  • 4
    Switches in Dart are more mature than other programming languages and they have more functionality. As an example In Dart, each case must have ‘break’, ‘continue’, ‘rethrow’, ‘return’ or ‘throw’ as a keyword. Please go through https://flutterrdart.com/dart-switch-case-statement-with-examples/ tutorial to learn about switch statement in Dart. – Waheed Akhtar Apr 05 '19 at 08:30

4 Answers4

111

The comparsion of double values using '==' is not very reliable and should be avoided (not only in Dart but in most languages).

You could do something like

methodname(num radians) {
  // you can adjust this values according to your accuracy requirements
  const myPI = 3142; 
  int r = (radians * 1000).round();

  switch (r) {
    case 0:
      // do something
      break;
    case myPI: 
      // do something else
      break;
  }
}

This question contains some additional information that might interest you

some more information:

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks you for the tip, in this case it is not a problem because radians in this case is produced programmatically and can be either 0 or PI exactly taken from the same place PI is written, hopefully it should be the same value exactly as well, but it does not answer the question: how should the types be tweaked to allow the switch case. I have had many issues with switch until now (first the case should be const - I cannot understand why not calculated value in runtime) now this.. I just want to understand the behaviour. Thanks – Peter StJ Jun 15 '14 at 12:11
  • @PeterStJ use `if/else` http://stackoverflow.com/questions/12398719/using-double-in-switch-statement It's common behavior in some(all?) languages. – JAre Jun 15 '14 at 12:27
  • @PeterStJ Also you can use string representation + you can truncate it for precision. – JAre Jun 15 '14 at 12:37
  • I don't know why exactly the case needs to be a constant expression but the language spec requires it (see the link I added). You can make a switch on `int` or `String` values or custom types that don't override `==` unless they allows to compare to an int or String value. The `switch` and all `case` expressions must be of the same type. – Günter Zöchbauer Jun 15 '14 at 12:42
  • 2
    @GünterZöchbauer With the const value branching can be predicted and it prevents some "dark magic" when, for example, value can be changed each time it's accessed. And with the "same type rule" you get commutativity for == operator. – JAre Jun 15 '14 at 15:53
  • @GünterZöchbauer thanks now I see, because PI is declared as double and my argument is declared as num. This was really a mystery to me (because I target JS currently and there is only one number type in v8). Now I see that in dart those are actually represented differently and are not only annotations for the developer, which is kind of strange because actually annotations should not change runtime... – Peter StJ Jun 16 '14 at 18:29
  • Annotations don't change the runtime. The type annotations allow the analyzer to show you possible problems while writing the code (before actually executing it). When you run code from DartEditor it is run in 'checked mode' by default, which actually enforces type checks at runtime. Types are actually only ignored when you run in production mode. You can define a Launch Configuration in DartEditor to achieve this or run `pub build` and run the result. I don't know if Dart cares about the difference of int/double in production mode. – Günter Zöchbauer Jun 16 '14 at 18:35
10

Here is example for switch case in Dart.

Q:Write a program to print the multiplication table of given numbers. Accept an input from the user and display its multiplication table

import 'dart:io';

void main(List<String> args) {
  print('enter a number from 1 to 7');

  var input = stdin.readLineSync();

  int day = int.parse(input!);

  switch (day) {
    case 1:
      print('Sunday');
      break;

    case 2:
      print('Monday');
      break;

    case 3:
      print('Tuesday');
      break;

    case 4:
      print('Wednesday');
      break;
    case 5:
      print('Thursday');
      break;

    case 6:
      print('Friday');
      break;
    case 7:
      print('Saturday');
      break;
    default:
      print(' invalid entry');
  }
}
1

I think that Dart 3's switch expression offers a much neater syntax for this.

bool methodname(num radians) {
  const myPI = 3142;
  int r = (radians * 1000).round();

  return switch (r) {
    myPI => true,
    _ => false,
  };
}
Christian Findlay
  • 6,770
  • 5
  • 51
  • 103
0

For a comparison of only two values better to use a ternary operator:

radians == 0
    ? //do something
    : //do something
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Fernando
  • 13
  • 2