2013-01-11 40 views
4

在阅读Play时!文字函数的隐式参数

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

Documentation解释implicit有:框架文件,我碰到这个片段来

或者,你可以从一个请求隐含检索会话

此外,我看到这篇文章: Literal with Implicit并且从逻辑上来说这个函数不能有隐式参数。

如果我也想通了,这是因为功能,违背方法有始终合同(接口)。

确实,例如,Function1[Int, Function1[Int, Int]]具有返回类型的第一个参数Int,因此阻止我们将其标注为implicit。这将导致有关其高级别返回类型的困惑:() => IntInt => Int ...

因此,什么前面的代码段与内隐的行为,因为需要先Action的参数是文字功能。

我想的原因,允许编译器接受这个代码是Action.apply()方法的多个签名:

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

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

回答

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的诀窍! Framework正在使用,请检查Controller以查找session函数。

作为一个侧面说明,上述封闭不说,它需要一个隐含的参数,它是一种语言功能,以避免必须做到以下几点:

Tester { myImplicitClass => 
    implicit val x = myImplicitClass 
    session * 20 
} 
当一个人想使用闭包参数作为

封闭体内的隐含价值。另外请注意,从Scala 2.9开始,你只能使用这个技巧的一个参数关闭。

+0

我没有玩!目前与我一起在电脑上安装,所以不幸的是,我无法进一步了解为什么这个与Play!编译,我设置了一个层次结构像Play一样!并且无法弄清楚“你可以通过请求隐式地获得会话”,然后直接从请求中删除访问并直接引用会话......这可能只是他们文档中的错误,但我不是非常肯定。 –

+0

我正在写一个可能的答案(对我自己的问题:)) – Mik378

+0

在我的示例中,隐式请求=>与隐式测试=>相同。另外,用你的替换调用它是没有意义的,因为它是一个函数的参数,而不是一个值。我将其重命名为“myImplicitClass”以使其更加清晰。 –