如何在Scala中找到隐式的来源? [英] How can I locate where an implicit comes from in Scala?

查看:91
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆