2016-02-24 68 views
3

我有一個自定義格式化程序(說MyFormatorg.joda.DateTime它提供了一個Format[org.joda.DateTime]'覆蓋'/'強制'某個隱式分辨率的安全方法

Play提供在play.api.libs.json包相同類別的默認格式。

我想在我的應用程序中使用MyFormat,而不是一個Play提供。我已經通過明確的進口/混入其中的伎倆但變更或省略期間,當這些得到去除,系列化默認播放格式和我結束了運行時錯誤做到了這一點。這似乎很容易出錯。

最終我希望我的代碼不要編譯,如果沒有MyFormatorg.joda.DateTime範圍內,只要有一個是必需的。

是否有這樣做的一個很好的和安全的方式?

+1

我認爲你可以優先考慮你自己隱含的唯一方法就是將它移到當前使用它的地方(這對你的情況不好,因爲重複)。你不能擴展格式並使用這種新類型嗎? – LMeyer

回答

0

你有幾個選擇,但他們都沒有將正是你想要的。問題的癥結在於Scala會在相關的伴侶對象中尋找隱含的東西。舉例來說,如果它需要找到一個隱含Format[DateTime],它看起來的Format同伴對象和DateTime同伴對象中。在這種情況下,在Format內有一個隱含的def,它會產生所需的(或者在你的情況下,不受歡迎的)Format[DateTime],並且沒有什麼可以擺脫它,缺少分叉和黑客入侵。


解決方法1:創建您的自定義格式的對象,並在全球導入:

package my.project 

object Formats { 
    implicit val dateTimeFormat: Format[DateTime] = ??? 
} 

(在其他文件)

import my.project.Formats._ 

Format[DateTime]導入到本地範圍將取代從Format對象中解析出的那個。但是,如果沒有它,你不能阻止你的代碼編譯(除非你有某種scalastyle規則或需要導入的東西)。


解決方法2:創建DateTime與它自己的Format的包裝,並給它一個隱式轉換爲DateTime

case class MyDateTime(dt: DateTime) { 
    implicit def toDateTime: DateTime = dt 
} 

object MyDateTime { 
    implicit val fmt: Format[MyDateTime] = ??? 
    implicit def fromDateTime(dt: DateTime): MyDateTime = MyDateTime(dt) 
} 

這不是一個完整的例子,而是一個關於如何實現它的想法。 DateTime可以與MyDateTime交換是最多的地方,但它可能需要其他含義圍繞MyDateTime旋轉。例如,當我嘗試使用Anorm時,我需要一個隱含的ToStatement[MyDateTime],可能還有其他一些 - 所以這是明顯的缺點。但是,這將明確避​​免使用默認的Format[DateTime]