Czy Dart obsługuje wyliczenia?

91

Czy Dart obsługuje wyliczenia? Na przykład:

enum myFruitEnum { Apple, Banana }

Pobieżne przeszukanie dokumentów sugeruje, że nie.

BraveNewMath
źródło
1
code.google.com/p/dart/issues/detail?id=88 - wygląda na to, że nie
Mat
tak. Dart obsługuje Enums
MJ Montes

Odpowiedzi:

156

Od wersji 1.8 możesz używać wyliczeń w następujący sposób:

enum Fruit {
  apple, banana
}

main() {
  var a = Fruit.apple;
  switch (a) {
    case Fruit.apple:
      print('it is an apple');
      break;
  }

  // get all the values of the enums
  for (List<Fruit> value in Fruit.values) {
    print(value);
  }

  // get the second value
  print(Fruit.values[1]);
}

Stare podejście przed 1.8:

class Fruit {
  static const APPLE = const Fruit._(0);
  static const BANANA = const Fruit._(1);

  static get values => [APPLE, BANANA];

  final int value;

  const Fruit._(this.value);
}

Te stałe statyczne w klasie są stałymi czasu kompilacji i tej klasy można teraz używać na przykład w switchinstrukcjach:

var a = Fruit.APPLE;
switch (a) {
  case Fruit.APPLE:
    print('Yes!');
    break;
}
Kai Sellgren
źródło
1
Używanie constnie zawsze jest możliwe (jeśli wyliczenie jest zbudowane z atrybutami, których nie można const). Dlatego nie użyłem go w mojej odpowiedzi (chociaż czasami używam constenum w moim kodzie).
Alexandre Ardhuin,
Przyjmę
2
@KaiSellgren Uwaga Myślę, że przewodnik po stylach został teraz zmieniony, więc wartości wyliczenia powinny być małymi literami wielbłąda zamiast wszystkich wielkich liter. Zobacz dartlang.org/articles/style-guide/…
Greg Lowe
2
Co List<Fruit> value?
Tom Russell,
1
Prawdopodobnie for (Fruit value in Fruit.values)
chciałeś
9

Z r41815 Dart ma natywną obsługę Enum, patrz http://dartbug.com/21416 i może być używany jak

enum Status {
  none,
  running,
  stopped,
  paused
}

void main() {
  print(Status.values);
  Status.values.forEach((v) => print('value: $v, index: ${v.index}'));
  print('running: ${Status.running}, ${Status.running.index}');
  print('running index: ${Status.values[1]}');
}

Wartość [Status.none, Status.running, Status.stopped, Status.paused]
: Status.none, indeks: 0
wartość: Status.running, indeks: 1
wartość: Status.stopped, indeks: 2
wartość: Status.paused, index: 3
działa: Status.running, 1
działa index: Status.running

Ograniczeniem jest to, że nie jest możliwe ustawienie wartości niestandardowych dla elementu wyliczeniowego, są one automatycznie numerowane.

Więcej szczegółów w tej wersji roboczej https://www.dartlang.org/docs/spec/EnumsTC52draft.pdf

Günter Zöchbauer
źródło
4

To i to mogą być odpowiedzi na Twoje pytanie:

... for the technology preview it was decided to leave it out and just 
use static final fields for now. It may be added later.

Nadal możesz zrobić coś takiego:

interface ConnectionState { }
class Connected implements ConnectionState { }
class Connecting implements ConnectionState { }
class Disconnected implements ConnectionState { }

//later
ConnectionState connectionState;
if (connectionState is Connecting) { ... }

który moim zdaniem jest bardziej przejrzysty w użyciu. Trochę trudniej jest zaprogramować strukturę aplikacji, ale w niektórych przypadkach jest to lepsze i przejrzyste.

user35443
źródło
Myślę, że w tym przykładzie lepiej byłoby pominąć interfejs i użyć klasy. Interfejs jest opcjonalną abstrakcją i
BraveNewMath
3

Wyliczenie powinno być dostępne w przyszłości. Ale dopóki Enum nie wyląduje , możesz zrobić coś takiego:

class Fruit {
  static final APPLE = new Fruit._();
  static final BANANA = new Fruit._();

  static get values => [APPLE, BANANA];

  Fruit._();
}
Alexandre Ardhuin
źródło
2

co z tym podejściem:

class FruitEnums {
  static const String Apple = "Apple";
  static const String Banana = "Banana";
}

class EnumUsageExample {

  void DoSomething(){

    var fruit = FruitEnums.Apple;
    String message;
    switch(fruit){
      case(FruitEnums.Apple):
        message = "Now slicing $fruit.";
        break;
      default:
        message = "Now slicing $fruit via default case.";
        break;
    }
  }
}
BraveNewMath
źródło
2
Sam bym tego nie zrobił. Zachowałbym nazwę wielkimi literami jako Fruit.APPLE. Następnie, gdybym chciał uzyskać tekstowe dane wyjściowe, miałbym mapę, która je tłumaczy lub osobno obsługę niektórych języków, gdybym chciał obsługiwać również inne języki. Myślę też, że switchstwierdzenia działają najlepiej na liczbach całkowitych, ponieważ wtedy można je skompilować do tabeli skoków.
Kai Sellgren
1

Tak! W rzeczywistości bardzo przydatne jest wykonywanie wyliczeń w Dart:

  enum fruits{
    BANANA, APPLE, ORANGE
  }
Beloin Sena
źródło
Małe litery są standardowe.
Pete Alvin
0

Po prostu użyj pliku klas typów.

Typy rzutek

łatwe, szybkie, wydajniejsze i bardziej pomocne.

mały problem, ta klasa jest ograniczona do pięciu różnych wyborów i plus jeden dla działa jako zerowa.

NabilJaran
źródło