我是scala和playframework的新手。有人可以将下面的以下片段翻译成普通英语吗?对于上下文中的上下文:http://www.playframework.org/documentation/2.0.4/ScalaSecurity
/**
* This method shows how you could wrap the withAuth method to also fetch your user
* You will need to implement UserDAO.findOneByUsername
*/
def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request =>
UserDAO.findOneByUsername(username).map { user =>
f(user)(request)
}.getOrElse(onUnauthorized(request))
}
答案 0 :(得分:22)
第1部分:首先让我们解决一下咖喱语法:
withUser
是一种采用f
类型的curried函数User => Request[AnyContent] => Result
的方法。它需要一个User
对象并返回另一个带Request
并返回Result
的函数。打破它,如果f
是那个功能,那么:
val g = f(user) // g is a function
val result = g(request) // returns a result
// same as:
val result = f(user)(request)
实际上,f
就像一个带有两个参数的函数,但不是调用f(a, b)
而是调用f(a)(b)
。
withAuth
也是一种采用curried函数的方法。它与withUser
的类型几乎相同。
第2部分:现在您如何使用这些方法:
正如here所述,play通过告诉它如何将Request
个对象转换为Result
个对象来定义应用程序逻辑。
withAuth
是一个辅助函数,负责为您进行身份验证并方便地检索用户名。所以你这样使用它:
def index = withAuth { username => implicit request =>
Ok(html.index(username))
}
它返回一个函数,它接受Request
并返回Result
,这就是游戏所需要的。但它需要的是一个curried函数(需要用户名)并返回一个函数(接受请求)。请求参数标记为隐式,因此可以隐式传递给需要隐式请求参数的任何函数/方法调用。出于解释的目的,只需忽略implicit
关键字。
第3部分:withUser
嗯,它的签名类似于withAuth
,目标是以相同的方式使用它,除了第一个参数是User
而不是String
。所以它必须采用User => Request => Result
。请求特征采用类型参数,该参数指示其内容的类型。这是AnyContent
。因此withUser
参数的正确类型为User => Request[AnyContent] => Result
。这意味着您将能够像这样使用它:
withUser { user => implicit request =>
// do something with user and request to return a result
}
如果你看一下withUser
的定义,它所做的只是致电withAuth
:
def withUser(f: User => Request[AnyContent] => Result) = withAuth {
// ...
}
因此它将返回与withAuth
相同的类型,这意味着它将返回一个将Request
转换为Result
的函数(参见上面的第2部分)。这意味着我们可以像这样使用它:
def index = withUser { user => implicit request =>
Ok(html.index(user))
}
作为withAuth
的参数传递的是一个curried函数。我介绍了中间val
,以便您可以按照以下类型进行操作:
username => // first param is the username as a String
implicit request => // second param is the request
// here we have to return a Result...
// we lookup the user - we may not have one:
val userOption: Option[User] = UserDAO.findOneByUsername(username)
// f is the code block that will be provided inside withUser { f }
// Part 1 explains the f(user)(request) syntax
// We call f to get a result, in the context of the Option monad
val resultOption: Option[Result] = userOption.map(user => f(user)(request))
// if we have a result, return it; otherwise return an error.
resultOption.getOrElse(onUnauthorized(request))