2014-02-03 4 views
4

Я прочитал this и this, но я до сих пор не понимаю (идиоматических) эквивалентный способ сделать это в ScalaScala/Java перечислений

enum Status { 
    OK(1, "Ok", "Okay"), 
    NOT_OK(5, "Not Ok", "Not Okay") 
    BAD(10, "Bad", "Run for your life") 

    int code; 
    String name; 
    String description; // custom fields 

    Status(int code, String name, String description) { 
     this.code = code; 
     this.name = name; 
     this.description = description; 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     for(Status status : Status.values) { // iterate through them 
      doStuff(status); 
     } 
    } 

    private doStuff(Status status) { 
     System.out.println(status.description); 
     // and more 
    } 
} 
+0

Я думаю, что название вопроса неверно – kan

+1

я не понимаю значение, что и Etag nginx связаны с перечислениями Scala. Etag - это хэш-значение, генерируемое сервером, которое HTTP-клиент может использовать для обнаружения изменения содержимого. –

+0

О, чувак, это было неловко. Я собирался задать вопрос «Может ли Nginx ETag прокси-контент?» на прошлой неделе, но я отбросил его после написания только названия. Когда задали этот вопрос, он, по-видимому, уже был установлен как заголовок. –

ответ

4

Там нет прямого соответствия между корпусом класса и перечислений или что-то действительно близкое к перечислениям. Но вы можете реализовать ту же логику так:

case class Status(code: Int, name: String, descr: String) 
object Status { 
val OK = Status(1, "Ok", "Okay"), 
val NOT_OK = Status(5, "Not Ok", "Not Okay") 
val BAD = Status(10, "Bad", "Run for your life") 
} 

Тогда, если вы хотите, вы можете поместить его в некоторых список называется значений:

import Status._ 
val values = List(OK, NOT_OK, BAD) 

, а затем сделать свой материал:

values.foreach(doStuff) 

Результат будет таким же, как в Java-версии

Если вам нужно выполнить различные действия, которые зависят от Д.С. по типу состояния, то вы можете пойти с поиском по шаблону:

sealed trait Status 
case class OK(code: Int, name: String, descr: String) extends Status 
case class Not_Ok(code: Int, name: String, descr: String) extends Status 
case class Bad(code: Int, name: String, descr: String) extends Status 

то в вашем DoStuff использование функции поиска по шаблону, например:

def doStuff(status: Status) = status match { 
    case OK(c, n, d) => // some code.. 
    // some code for other cases 
} 

val values = List(OK(1, "Ok", "Okay"), Not_Ok(5, "Not Ok", "Not Okay"), Bad(10, "Bad", "Run for your life")) 

value.foreach(doStuff) 
+2

Я предпочитаю ваш подход «запечатанный статус», но я бы использовал «случайный объект» вместо «case class», чтобы объявить три значения «enum». – DaoWen

+0

@DaoWen в случае, если объекты объекта расширяют признак или класс, у вас не будет неявного применения/неприменения для сопоставления шаблонов. – 4lex1v

10

В Scala вы можете создать структуру Enumeration, которая близка на "enum" из Java. В принципе, вам нужно просто расширить scala.Enumeration class и расширить класс Val, если вам нужен более сложный класс в качестве перечисления. В противном случае вы можете использовать класс Val по умолчанию, который принимает Int или String или Both. Ниже приведена версия Scala вашего Java-кода.

object Status extends Enumeration { 

    case class StatusVal(code: Int, name: String, description: String) extends Val 

    val OK = StatusVal(1, "Ok", "Okay") 
    val NOT_OK = StatusVal(1, "Not Ok", "Not Okay") 
    val BAD = StatusVal(1, "Bad", "Run for your life") 
} 

object Application extends App { 
    Status.values foreach (s => println(s.asInstanceOf[StatusVal].description)) 
} 
+0

Вы хотели использовать 1 в качестве идентификатора для каждого StatusVal? Кроме того, было бы лучше, если StatusVal будет расширять 'Val (код, имя)'? – mrog

+0

@mrog, нет, '1' - это просто опечатка. Вы можете использовать любой Int. – cyrillk

0

Вы можете использовать sealed class + case object. Единственная часть, которую вы не можете получить с этим подходом является методом values, но вы можете использовать this answer реализовать метод values так:

sealed class Status(val code: Int, val name: String, val description: String) 
object Status { 
    def values: Set[Status] = macro SealedExample.values_impl[Status] 

    case object OK extends Status(1, "Ok", "Okay") 
    case object NOT_OK extends Status(5, "Not Ok", "Not Okay") 
    case object BAD extends Status(10, "Bad", "Run for your life") 
} 

def doStuff(status: Status) = println(status.description) 

for {s <- Status.values} 
    doStuff(s) 
// Okay 
// Not Okay 
// Run for your life 

 Смежные вопросы

  • Нет связанных вопросов^_^