10

有人可以揭开这段代码的神秘面纱,它是 Play20 框架中 zentasks 示例的一部分。我很好奇它是如何工作的,因为我是从 Java 开始接触 Scala 的新手,所以很多事情都难以理解。

def IsAuthenticated(f: => String => Request[AnyContent] => Result) = 
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(request => f(user)(request))
  }
4

2 回答 2

16

您需要稍微拆分签名。f是一个函数,它接受一个尚未计算的字符串=> String并返回另一个接受 aRequest[AnyContent]并返回结果的函数。

Security.Authenticated调用接受两个参数列表。一个有usernameonUnauthorized。第二个函数接受用户并返回一个动作。

Action.apply方法接受一个函数Request[AnyContent] => Result

因此, f 以“咖喱”的方式被称为。即调用第一个函数,然后立即使用生成的函数f(user)(request)

这是脱糖(至少,尽我所能)和丑陋的东西:

def isAuthenticated(f: => String => Request[AnyContent] => Result) =
  Security.Authenticated(username, onUnauthorized) { user: String =>
     Action.apply { request: Request[AnyContent] =>
       val hiddenTmp: Request[AnyContent] => Result = f(user)
       hiddenTemp.apply(request)
     }
  }

您可以看到编译器正在做一些删除类型注释的工作。希望这有助于解释它是如何脱糖成原始 scala 的。本质上,函数做了很多功能组合。

于 2011-12-21T22:48:31.567 回答
2

首先是我的回答的用户指南:我将使用斜体来表示一个未明确命名的函数(请参阅匿名函数)。

IsAuthenticated 是一种将参数 f 作为参数的方法。

f 是一个以Y作为参数并生成 Result 实例的函数

Y是一个以Z作为参数并生成 Request[AnyContent] 实例的函数

Z是一个不带参数并返回字符串的函数

IsAuthenticated 调用 Security.Authenticated,传递用户名和 onUnauthorized(当用户无权执行请求的操作时调用的函数)。

我自己并不完全确定过去发生了什么——我对 Scala 还不是很好——但我的猜测是 Security.Authenticated 是一个案例类,下面的等价于子类化它并在 java 中添加一个构造函数:

{
  Action(request => f(user)(request))
}

如果我的大部分假设是正确的,那么将调用 Action(这是 Security.Authenticated 上的一种方法),并将A作为参数传递。

A是一个函数,它接受一个请求对象(我猜是这个类名)并产生一个结果。这里隐含了 Result 的使用,因为A的实现是对 f 的调用。

因此,当 Security.Authenticated 的子类被实例化时,会调用 Action,它会针对某些操作(指定为 String)对用户进行身份验证,然后如果用户通过身份验证,则返回可能由 Action 调用的 f(原始参数)(上述认证后)。对 f 的调用返回一个 Result,它也是一个函数。然后最终以 request (已传递给A)作为参数调用 Result。

于 2011-12-21T22:55:16.343 回答