這比什麼都重要設計問題...使用Scala的case類作爲事實上的地圖
我真的很喜歡Scala的case類,並經常使用它們。然而,我發現我經常在Options
(或者說,Lift的Boxes
)中包裝我的參數,並設置默認值以允許靈活性並考慮到用戶可能並不總是指定所有參數。我認爲我採用了這種做法。
我的問題是,這是一個合理的方法?鑑於所有內容都是可選的,因此可以進行大量的樣板和檢查,以確定是否我不僅僅使用像Map[String, Any]
這樣的案例類,並且懷疑我是否僅僅使用Map
就更好。
讓我給你一個真實的例子。在這裏,我正在模擬匯款:
case class Amount(amount: Double, currency: Box[Currency] = Empty)
trait TransactionSide
case class From(amount: Box[Amount] = Empty, currency: Box[Currency] = Empty, country: Box[Country] = Empty) extends TransactionSide
case class To(amount: Box[Amount] = Empty, currency: Box[Currency] = Empty, country: Box[Country] = Empty) extends TransactionSide
case class Transaction(from: From, to: To)
我覺得比較容易理解。在這個最簡單的,我們可能會宣佈一個Transaction
像這樣:
val t = Transaction(From(amount=Full(Amount(100.0)), To(country=Full(US)))
我已經能想象你認爲這是冗長。如果我們指定的一切:
val t2 = Transaction(From(Full(Amount(100.0, Full(EUR))), Full(EUR), Full(Netherlands)), To(Full(Amount(150.0, Full(USD))), Full(USD), Full(US)))
在另一方面,儘管有扔Full
到處,你仍然可以做一些很好的模式匹配:
t2 match {
case Transaction(From(Full(Amount(amount_from, Full(currency_from1))), Full(currency_from2), Full(country_from)), To(Full(Amount(amount_to, Full(currency_to1))), Full(currency_to2), Full(country_to))) if country_from == country_to => Failure("You're trying to transfer to the same country!")
case Transaction(From(Full(Amount(amount_from, Full(currency_from1))), Full(currency_from2), Full(US)), To(Full(Amount(amount_to, Full(currency_to1))), Full(currency_to2), Full(North_Korea))) => Failure("Transfers from the US to North Korea are not allowed!")
case Transaction(From(Full(Amount(amount_from, Full(currency_from1))), Full(currency_from2), Full(country_from)), To(Full(Amount(amount_to, Full(currency_to1))), Full(currency_to2), Full(country_to))) => Full([something])
case _ => Empty
}
這是一個合理的做法?我會更好地使用Map
?或者我應該使用案例類,但以不同的方式?也許使用整個層次的案例類來表示具有不同指定信息量的交易?
感謝鏈接到鏡頭談話,我現在正在聽它。但有沒有網頁的教程?我想了解更多! – pr1001
從來沒有爲scala找到它們,但應該爲haskell而存在。 – paradigmatic