2017-12-02 141 views
0

我想建立一個沒有任何相關性的接口,只有Scala庫集裝箱類型Type類

讓我們想象一下,這是我想要的東西:

iface.jar

​​

如您所見,它不包含任何導入。

讓我們去實現:

iface_implementation1.jar

import play.api.libs.json._ 

trait myPlayJsonImpl extends jsonIface[JsValue] { 

     def turnJsonIntoClass[T](t: JsValue) { t.as[T] } 

} 

但是這不會編譯,因爲作爲[T]需要隱讀[T]

所以我改寫了我的iface like that:

trait jsonIface[JsValue] { 

    type metaInfo[T] 

    def turnJsonIntoClass[T](t: JsValue)(implicit meta: metaInfo[T]) 

} 

玩JSON實現了一套看起來像這樣:

import play.api.libs.json._ 

trait myPlayJsonImpl extends jsonIface[JsValue] { 

    type conv[M] = Reads[M] 

    def turnJsonIntoClass[T](t: JsValue)(implicit reads: Reads[T]) { t.as[T] }  

} 

和json4s看起來像這樣:

import org.json4s.JsonAST._ 

trait json4sImpl extends jsonIface[JValue] { 

    type conv[M] = Manifest[M] 

    def turnJsonIntoClass[T](t: JsValue)(implicit reads: Manifest[T]) { t.extract[T] }  

} 

這編譯但是當你開始使用類型級特性的工作,它看起來笨重

回答

0

通常你繼續這樣做,而不是與OOP特徵一起工作:

import org.json4s.Formats 
import org.json4s.JsonAST.JValue 
import play.api.libs.json.{JsValue, Reads} 

trait jsonIface[JsValue, T] { 
    def turnJsonIntoClass(t: JsValue): T 
} 

object jsonIface { 
    implicit def json4sImpl[T](implicit formats: Formats, manifest: Manifest[T]): jsonIface[JValue, T] = new jsonIface[JValue, T] { 
    def turnJsonIntoClass(t: JValue): T = t.extract[T] 
    } 

    implicit def myPlayJsonImpl[T](implicit reads: Reads[T]): jsonIface[JsValue, T] = new jsonIface[JsValue, T] { 
    def turnJsonIntoClass(t: JsValue): T = t.as[T] 
    } 
} 

object jsonIface { 
    implicit def json4sImpl[T](implicit formats: Formats, manifest: Manifest[T]): jsonIface[JValue, T] = (t: JValue) => t.extract[T] 

    implicit def myPlayJsonImpl[T](implicit reads: Reads[T]): jsonIface[JsValue, T] = (t: JsValue) => t.as[T] 
}