トランプを表現するクラスを書いてみた。
こんな書き方できんのかよ...
Hello.scala
package example
import example.Suits._
import example.ValueHolder._
object Hello {
def main(args: Array[String]) = {
println(Ace of Spades) // すごい
println(2 of Diamonds) // とてもすごい
}
}
sealed trait Suits {
def emoji: String
}
object Suits {
object Diamonds extends Suits {
override def emoji: String = "♦"
}
object Clubs extends Suits {
override def emoji: String = "♣"
}
object Hearts extends Suits {
override def emoji: String = "♥"
}
object Spades extends Suits {
override def emoji: String = "♠"
}
}
case class Card(
val suits: Suits,
val number: Int
) {
override def toString(): String = {
val numberString = number match {
case 1 => "A"
case 11 => "J"
case 12 => "Q"
case 13 => "K"
case _ => number.toString()
}
s"(${suits.emoji},$numberString)"
}
}
abstract class ValueHolder {
val value: Int
def of(suits: Suits): Card = Card(suits, value)
}
object ValueHolder {
object Ace extends ValueHolder {
override val value: Int = 1
}
implicit class IntValueHolder(override val value: Int)
extends ValueHolder {}
}
出力
(♠,A)
(♦,2)
※「ハートの2000」みたいなカードを生成できる点はご愛嬌
解説
abstract class ValueHolder {
val value: Int
def of(suits: Suits): Card = Card(suits, value)
}
を実装すると以下のように書けるようになる。
val v: ValueHolder = ??? // なんかうまいこと ValueHolder のインスタンスを生成する
val card = v.of(Spades)
Scalaは特定の条件を満たすとメソッド呼び出しの「.」を省略してスペースで代用できる(らしい)し、引数が1つのメソッドは引数を括弧でくくる代わりにスペースで代用できる(らしい)ので、以下のように書ける。
val card = v of Spades
さらに
implicit class IntValueHolder(override val value: Int)
extends ValueHolder {}
によって、Int
をValueHolder
として扱うことができるようになるので、
val card = 2 of Diamonds
と書ける。