Случай возражает по сравнению с Перечислениями в Scala

Есть ли какие-либо инструкции лучшей практики по когда к классам варианта использования (или объекты случая) по сравнению с расширяющимся Перечислением в Scala?

Они, кажется, предлагают некоторые из тех же преимуществ.

225
задан Jacek Laskowski 8 May 2015 в 23:04
поделиться

3 ответа

One big difference is that Enumerations come with support for instantiating them from some name String. For example:

object Currency extends Enumeration {
   val GBP = Value("GBP")
   val EUR = Value("EUR") //etc.
} 

Then you can do:

val ccy = Currency.withName("EUR")

This is useful when wishing to persist enumerations (for example, to a database) or create them from data residing in files. However, I find in general that enumerations are a bit clumsy in Scala and have the feel of an awkward add-on, so I now tend to use case objects. A case object is more flexible than an enum:

sealed trait Currency { def name: String }
case object EUR extends Currency { val name = "EUR" } //etc.

case class UnknownCurrency(name: String) extends Currency

So now I have the advantage of...

trade.ccy match {
  case EUR                   =>
  case UnknownCurrency(code) =>
}

As @chaotic3quilibrium pointed out (with some corrections to ease reading):

Regarding "UnknownCurrency(code)" pattern, there are other ways to handle not finding a currency code string than "breaking" the closed set nature of the Currency type. UnknownCurrency being of type Currency can now sneak into other parts of an API.

It's advisable to push that case outside Enumeration and make the client deal with an Option[Currency] type that would clearly indicate there is really a matching problem and "encourage" the user of the API to sort it out him/herself.

To follow up on the other answers here, the main drawbacks of case objects over Enumerations are:

  1. Can't iterate over all instances of the "enumeration". This is certainly the case, but I've found it extremely rare in practice that this is required.

  2. Can't instantiate easily from persisted value. This is also true but, except in the case of huge enumerations (for example, all currencies), this doesn't present a huge overhead.

218
ответ дан 23 November 2019 в 03:55
поделиться

Еще один недостаток классов case по сравнению с Enumerations, когда вам нужно выполнить итерацию или фильтрацию по всем экземплярам. Это встроенная возможность Enumeration (а также перечислений Java), в то время как классы case не поддерживают такую ​​возможность автоматически.

Другими словами: «нет простого способа получить список полного набора перечисляемых значений. с классами case ".

8
ответ дан 23 November 2019 в 03:55
поделиться

Преимущества использования классов case над перечислениями:

  • При использовании закрытых классов case компилятор Scala может определить, полностью ли указано совпадение, например, когда все возможные совпадения поддерживаются в объявлении соответствия. С перечислениями компилятор Scala не может сказать.
  • Классы case, естественно, поддерживают больше полей, чем перечисление на основе значений, которое поддерживает имя и идентификатор.

Преимущества использования перечислений вместо классов case:

  • Обычно перечисления будет немного меньше кода для написания.
  • Перечисления немного легче понять тем, кто плохо знаком со Scala, поскольку они распространены в других языках.

В общем, если вам просто нужен список простых констант по имени, используйте перечисления. Иначе,

26
ответ дан 23 November 2019 в 03:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: