簡體   English   中英

來自周圍范圍的隱式參數解析

[英]Implicit parameter resolution from surrounding scope

我不喜歡將隱式參數引入代碼中,因此我想在哪里使用它們來封裝它們的用法。 所以我試圖定義一個對象,它既包含對異常處理的spray-json的調用,又包含每個模型類的默認隱式JsonFormats。 但是,隱式參數不會被解析,除非它們被導入到客戶端,調用代碼,這正是我不想要它們的地方。 這是我到目前為止(它沒有解決隱式格式化程序),有沒有辦法讓我得到我想要的工作?

package com.rsslldnphy.json

import com.rsslldnphy.models._
import spray.json._

object Json extends DefaultJsonProtocol {

  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)

  def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
    try { Some(JsonParser(s).convertTo[T]) }
    catch { case e: DeserializationException => None }
  }
}

NB。 JsonFormat是一種JsonReader

編輯:這是我寫的基於@ paradigmatic的第二個建議(我無法工作,我仍然Cannot find JsonReader or JsonFormat type class for T )。 我想念什么嗎?

object Protocols extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)
}

object Json {

  def parse[T](s:String): Option[T] = {
    import Protocols._
    try { Some(JsonParser(s).convertTo[T]) }
    catch { case e: DeserializationException => None }
  }
}

為了記錄,這是一個有效的代碼片段,但我正在努力避免,因為它需要太多的客戶端代碼(即它需要在范圍內具有含義):

object Json extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)
}

object ClientCode {
  import Json._
  def person(s: String): Person = JsonParser(s).convertTo[Person]
}

您可以在隨播對象中聲明含義:

object Person {
  implicit val personFormat: JReader[Person] = jsonFormat1(Person)
}
object Animal {
  implicit val animalFormat: JReader[Animal] = jsonFormat1(Animal)
}

隱式解決規則非常復雜。 您可以在此博客文章中找到更多信息。 但是如果編譯器正在尋找類型類T[A] ,它將在類/特征A的伴隨對象中(很快或稍后)查找它。

編輯:如果問題只是范圍“污染”的問題,你可以介紹一些大括號。 使用您的代碼示例,您可以將函數解析調用為:

package com.rsslldnphy.json

import com.rsslldnphy.models._
import spray.json._

object Json extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)

  def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
    try { Some(JsonParser(s).convertTo[T]) }
    catch { case e: DeserializationException => None }
  }
}

object JsonFacade {
    def optParse[T]( s: String ): Option[T] = {
      import Json._
      parse[T]( s )
    }
}

這里僅暗示“污染” optParse方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM