4

在阅读播放!框架文档,我遇到了这个片段:

def index = Action { implicit request =>
  session.get("connected").map { user =>
    Ok("Hello " + user)
  }.getOrElse {
    Unauthorized("Oops, you are not connected")
  }
}

文档在那里解释implicit

或者,您可以从请求中隐式检索 Session

此外,我读了这篇文章:Literal with Implicit从逻辑上讲,函数不能有隐式参数。

如果我想通了,这是因为与方法相反的函数总是有一个契约(接口)。

实际上,例如,Function1[Int, Function1[Int, Int]]作为返回类型的第一个参数 an Int,因此阻止我们将其注释为implicit。这将导致对其高级返回类型的混淆:() => IntInt => Int ...

因此,前面的代码片段的行为是隐式的,因为 firstAction的必需参数是一个文字函数。

我猜允许编译器接受此代码的原因是Action.apply()方法的多重签名:

  • def apply(block: Request[AnyContent] => Result): Action[AnyContent]
  • def apply(block: => Result): Action[AnyContent](重定向到第一个)

由于第二个不需要某些参数,因此是否在存在文字函数的隐式参数的情况下选择了这个?

4

1 回答 1

6

考虑以下代码:

class MyImplicitClass(val session: Int)
object Tester {
  def apply(fun: MyImplicitClass => Int): Int = ???
  def apply(fun: => Int): Int = ???
}
Tester { implicit myImplicitClass => session * 20}

如果这个函数:

def session(implicit myImplicitClass: MyImplicitClass): Int = myImplicitClass.session

在范围内,那么第一个代码片段将编译,因为显然隐式参数myImplicitClass将传递给函数 session以访问字段 myImplicitClass.session,允许您省略字段访问。这正是 Play 的诀窍!框架正在使用,查看Controller功能session

作为旁注,上面的闭包并不是说它需要一个隐式参数,它是一种语言特性,可以避免必须执行以下操作:

Tester { myImplicitClass => 
  implicit val x = myImplicitClass
  session * 20
}

当一个人想要使用闭包参数作为闭包主体中的隐式值时。另请注意,从 Scala 2.9 开始,此技巧仅限于使用 1 个参数的闭包。

于 2013-01-11T01:18:03.860 回答