如何在Scala中找到隐式的来源? [英] How can I locate where an implicit comes from in Scala?
问题描述
简短问题:
有没有办法让scala编译器告诉我在程序中给定点使用的某个隐式声明在哪里?
Is there a way to ask the scala compiler to tell me where a certain implicit used at a given point in a program was declared ?
如果没有,是否可以手动遵循一种算法来发现自己声明了隐式变量的位置?
If not, is there an algorithm that I can follow manually to find out myself where an implicit was declared ?
常见问题:
我正在遵循简单的喷雾器教程.
I am following simple spray crud tutorial.
In the code snippet below (coming the this repo for the tutorial):
pathEnd {
post {
entity(as[Question]) { question =>
completeWithLocationHeader(
resourceId = questionService.createQuestion(question),
ifDefinedStatus = 201, ifEmptyStatus = 409)
}
}
} ~
as
采用类型FromRequestUnmarshaller[T]
的隐式(完整源
as
takes an implicit of type FromRequestUnmarshaller[T]
(full source here):
def as[T](implicit um: FromRequestUnmarshaller[T]) = um
当我问IntelliJ隐式信息的来源(使用CMD + SHIFT + P)时,我得到:
and when I ask IntelliJ where this implicit comes from (using CMD+SHIFT+P), I get:
当我遵循第一个提示我明白了:
and when I follow the first hint I get this:
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
的:
this does not help me to figure out where the implicit FromRequestUnmarshaller[T]
comes from because I cannot figure out how the trait UnmarshallerLifting
gets mixed into QuestionResource
if I inspect the class hierarchy:
I inspect the traits that look like they might contain this implict, for example this trait,but it does not contain the implicit:
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个不同的地方后,我感到沮丧.
after looking at 20 different places I become frustrated.
是否有一种方法可以要求scala编译器告诉我程序(在本示例中为)被宣告了吗?
Is there a way to ask the scala compiler to tell me where a certain implicit (in this example FromRequestUnmarshaller[T]
) used at a given point in a program (in this example here) was declared ?
如果没有,是否可以手动遵循一种算法来发现自己声明了隐式变量的位置?
If not, is there an algorithm that I can follow manually to find out myself where an implicit was declared ?
我在Google/SOF上寻找了这个问题,但发现的提示没有帮助.我还通过了此,但我仍然不知道FromRequestUnmarshaller[T]
在哪里来自.
I looked for this question on Google/SOF but the hints I found did not help. I also went through this and I still don't know where the FromRequestUnmarshaller[T]
comes from.
推荐答案
我这样做了(如迈克尔评论中所建议的那样):
I did this (as suggested in Michael's comment):
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
This tells directly where the implicit is coming from : Deserializer.fromRequestUnmarshaller
此外,这是另一种方式,通过使用InteliJ的搜索使用功能:
Also, here is an other way, by using InteliJ's search usage function:
这篇关于如何在Scala中找到隐式的来源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!