私は、取引されるすべての主要通貨を含む基本的な列挙型通貨を持っています。 EUR
、USD
、JPY
などです。このコードは、1回書くか生成することができます。しかし、私はまた、すべての通貨ペアの組み合わせに対して強力な列挙型を持っていたいと思います。 EURCHF
、USDCHF
などScalaには、このような派生した列挙型を動的に構築するための規定がありますか?私も外からのいくつかのスクリプトジェネレータでそれを行うことができます...しかし、それは可能かどうか疑問に思う。ScalaでEnum型を動的に作成する方法は?
object Ccy extends Enumeration {
type Type = Value
val USD = Value("USD")
val CHF = Value("CHF")
val EUR = Value("EUR")
val GBP = Value("GBP")
val JPY = Value("JPY")
}
object CcyPair extends Enumeration {
type Type = Value
// ??? Ccy.values.toSeq.combinations(2) ...
}
これは私のソリューションを実装したリファレンスとして受け入れ答えを使用してUPDATE:
import scala.language.dynamics
object CcyPair extends Enumeration with Dynamic {
type Type = Value
/*
* contains all currency combinations including the symmetric AB and BA
*/
private val byCcy: Map[(Ccy.Value, Ccy.Value), Value] =
Ccy.values.toSeq.combinations(2).map { case Seq(c1, c2) =>
Seq(
(c1, c2) -> Value(c1.toString + c2.toString),
(c2, c1) -> Value(c2.toString + c1.toString)
)
}.flatten.toMap
/**
* reverse lookup to find currencies by currency pair, needed to find
* the base and risk components.
*/
private val revByCcy = byCcy.toSeq.map { case (((ccyRisk, ccyBase), ccyPair)) =>
ccyPair -> (ccyRisk, ccyBase)
}.toMap
def apply(ccy1: Ccy.Value, ccy2: Ccy.Value): Value = {
assert(ccy1 != ccy2, "currencies should be different")
byCcy((ccy1, ccy2))
}
implicit class DecoratedCcyPair(ccyPair: CcyPair.Type) {
def base: Ccy.Type = {
revByCcy(ccyPair)._1
}
def risk: Ccy.Type = {
revByCcy(ccyPair)._2
}
def name: String = ccyPair.toString()
}
def selectDynamic(ccyPair: String): Value = withName(ccyPair)
}
と同様に、私は物事を行うことができます:Scalaの中に魔法はありません
val ccyPair = CcyPair.EURUSD
// or
val ccyPair = CcyPair(Ccy.EUR, Ccy.USD)
// and then do
println(ccyPair.name)
// and extract their parts like:
// print the base currency of the pair i.e. EUR
println(CcyPair.EURUSD.base)
// print the risk currency of the pair i.e. USD
println(CcyPair.EURUSD.risk)
うわー、素晴らしい答え!ありがとうございました! –
あなたの答えに 'CcyPair2.USDCHF'をして魔法のように定義されていますが、私にとっては存在しません... –
@GiovanniAzuaはい、それは' CcyPair2'の定義が 'Dynamic'を拡張しているからです。 'selectDynamic'がオーバーライドされています。詳細については、https://stackoverflow.com/questions/15799811/how-does-type-dynamic-work-and-how-to-use-itをご覧ください。コンパイル時ではなくランタイムエラーが発生するため、ここで使用することはお勧めできません。例として示しました。 – Kolmar