簡體   English   中英

在Scala中組織枚舉

[英]Organizing enumerations in Scala

抱歉這個冗長的問題:

說我有一個動物清單,我想把它們分開:

BasicAnimal = {Cat, Dog}
Carnivore = {Cat, Dog, Dragon}
Herbivore = {Cat, Dog, Horse}

現在,這些動物也必須住在某個地方。 所以有一個

BasicShelter with a method shelter(animal: BasicAnimal)
Den with a method shelter(animal: Carnivore)
Shed with a method shelter(animal: Herbivore)

在Scala中實現此功能的最佳方法是什么? 一次嘗試是:

class BasicAnimal extends Enumeration{
   val Cat, Dog = Value
}
class Carnivore extends BasicAnimal{
   val Dragon = Value
}
class Herbivore extends BasicAnimal{
   val Horse = Value
}

然后

class BasicHouse{
  def shelter(animal: BasicAnimal) = {//lots of code}
}
class Den{
  def shelter(animal: Carnivore) = {
  //again lots of code, but the cases dealing with Cat and Dog can be relegated to super.shelter
  }
}
class Shed{
  //the same
}

可悲的是,這不起作用。 來自食肉動物的狗與BasicAnimal中的狗不同。 那就是Carnivore.Dog == BasicAnimal.Dog返回false,因此,在Den中重用BasicHouse代碼的唯一方法是使用一個相當hacky的平等方法來比較枚舉的字符串(或類似的東西)。 它有效,但它非常不潔凈。 你能看到其他任何可能嗎?

根據@ paradigmatic的答案,但有一些增強功能:

sealed abstract trait BasicAnimal
sealed abstract trait Carnivore extends BasicAnimal
sealed abstract trait Herbivore extends BasicAnimal
sealed abstract trait Omnivore extends Carnivore with Herbivore

case object Dog extends Omnivore
case object Cat extends Omnivore
case object Dragon extends Carnivore
case object Horse extends Herbivore

使特征抽象允許您利用模式匹配中的完整性檢查(否則會警告未嘗試匹配特征本身)

Omnivore特征消除了一些重復,也有助於模式匹配

使用extends而不是自我鍵入只是更簡潔,更直觀

case object代替object主要是為了更好地記錄代碼的意圖,並且還提供了一個理智的toString實現

枚舉的另一種解決方案是使用sealed trait來定義枚舉。

用你的例子:

sealed trait BasicAnimal
sealed trait Carnivore { self: BasicAnimal => }
sealed trait Herbivore { self: BasicAnimal => }

object Dog extends BasicAnimal with Carnivore with Herbivore
object Cat extends BasicAnimal with Carnivore with Herbivore
object Dragon extends BasicAnimal with Carnivore
object Horse extends BasicAnimal with Herbivore

這比Enumeration更靈活,但是你失去了輕易枚舉所有值的可能性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM