2016-12-29 35 views
2

短的問題:我怎樣才能找到一個隱含的來自Scala的地方?

有沒有辦法問Scala編譯器來告訴我,在程序中給定的點使用的規定隱含宣佈?

如果沒有,是否有一個算法,我可以手動跟蹤找出自己在隱式聲明的位置?

長的問題:

我下面簡單的噴污物tutorial

在下面的代碼段(即將該this回購本教程):

pathEnd { 
    post { 
    entity(as[Question]) { question => 
     completeWithLocationHeader(
     resourceId = questionService.createQuestion(question), 
     ifDefinedStatus = 201, ifEmptyStatus = 409) 
     } 
    } 
} ~ 

as採用隱式FromRequestUnmarshaller[T]型的(完整的源here):

def as[T](implicit um: FromRequestUnmarshaller[T]) = um 

,當我問IntelliJ在哪裏隱含來自(使用CMD + SHIFT + P),我得到:

enter image description here 當我跟隨第一hint我得到這個:

trait UnmarshallerLifting { 

    implicit def fromRequestUnmarshaller[T](implicit um: FromMessageUnmarshaller[T]): FromRequestUnmarshaller[T] = 
    new FromRequestUnmarshaller[T] { 
     def apply(request: HttpRequest): Deserialized[T] = um(request) 
    } 
... 

這並不能幫助我找出其中隱含FromRequestUnmarshaller[T]來自因爲我想不通性狀UnmarshallerLifting如何混合到QuestionResource如果我檢查類層次:

enter image description here

我檢查那個樣子,他們可能含有這種內隱特質,例如this特質,但它不包含隱式:

trait MarshallingDirectives { 
    import BasicDirectives._ 
    import MiscDirectives._ 
    import RouteDirectives._ 

    /** 
    * Unmarshalls the requests entity to the given type passes it to its inner Route. 
    * If there is a problem with unmarshalling the request is rejected with the [[spray.routing.Rejection]] 
    * produced by the unmarshaller. 
    */ 
    def entity[T](um: FromRequestUnmarshaller[T]): Directive1[T] = 
    extract(_.request.as(um)).flatMap[T :: HNil] { 
     case Right(value)       ⇒ provide(value) 
     case Left(ContentExpected)     ⇒ reject(RequestEntityExpectedRejection) 
     case Left(UnsupportedContentType(supported)) ⇒ reject(UnsupportedRequestContentTypeRejection(supported)) 
     case Left(MalformedContent(errorMsg, cause)) ⇒ reject(MalformedRequestContentRejection(errorMsg, cause)) 
    } & cancelAllRejections(ofTypes(RequestEntityExpectedRejection.getClass, classOf[UnsupportedRequestContentTypeRejection])) 

    /** 
    * Returns the in-scope FromRequestUnmarshaller for the given type. 
    */ 
    def as[T](implicit um: FromRequestUnmarshaller[T]) = um 

    /** 
    * Uses the marshaller for the given type to produce a completion function that is passed to its inner route. 
    * You can use it do decouple marshaller resolution from request completion. 
    */ 
    def produce[T](marshaller: ToResponseMarshaller[T]): Directive[(T ⇒ Unit) :: HNil] = 
    extract { ctx ⇒ (value: T) ⇒ ctx.complete(value)(marshaller) } & cancelAllRejections(ofType[UnacceptedResponseContentTypeRejection]) 

    /** 
    * Returns the in-scope Marshaller for the given type. 
    */ 
    def instanceOf[T](implicit m: ToResponseMarshaller[T]) = m 

    /** 
    * Completes the request using the given function. The input to the function is produced with the in-scope 
    * entity unmarshaller and the result value of the function is marshalled with the in-scope marshaller. 
    */ 
    def handleWith[A, B](f: A ⇒ B)(implicit um: FromRequestUnmarshaller[A], m: ToResponseMarshaller[B]): Route = 
    entity(um) { a ⇒ RouteDirectives.complete(f(a)) } 
} 

object MarshallingDirectives extends MarshallingDirectives 

看了20個不同的地方後,我變得沮喪。

有沒有辦法讓scala編譯器告訴我在一個程序中的某個給定點(在這個例子中是here)聲明的某個隱式(在這個例子中是FromRequestUnmarshaller[T])在哪裏?

如果沒有,是否有一個算法,我可以手動跟蹤找出自己在隱式聲明的位置?

我在Google/SOF上找了這個問題,但是我發現的提示沒有幫助。我也經歷了this,我仍然不知道FromRequestUnmarshaller[T]來自哪裏。

+1

也許您在尋找:http://stackoverflow.com/questions/34903520/figuring-out-chain-of-implicit-invocations/34903876#34903876? –

+0

很好,謝謝,我有一個看看。 – jhegedus

回答

4

通常我在編譯器中啓用-Xlog-implicits以查看蘊含情況。

此外噴霧也被棄用,以支持akka-http。我建議切換。

+0

我試過了,它不會告訴我隱式來自哪裏,它只會抱怨被試過但不工作的隱含:( – jhegedus

2

我這樣做(在邁克爾的意見建議):

import scala.reflect.runtime.universe.reify 
    println(reify(entity(as[Question]))) 

印刷:

Expr[spray.routing.Directive1[spray_examples.plain_rest.danielasfregola.quiz.management.entities.Question]](QuestionResource.entity(QuestionResource.as[Question](Deserializer.fromRequestUnmarshaller(Deserializer.fromMessageUnmarshaller(QuestionResource.json4sUnmarshaller(ManifestFactory.classType(classOf[spray_examples.plain_rest.danielasfregola.quiz.management.entities.Question]))))))) 

這直接告訴其中隱含的是來自:Deserializer.fromRequestUnmarshaller

而且,在這裏是另一種方式,通過使用InteliJ的搜索使用功能:

enter image description here