我有一个这样实现的控制器操作:
def doChangePassword = deadbolt.Restrict(List(Array(Application.USER_ROLE_KEY)))()
{ request => // <<<<<<<<<<<< here is the request
Future {
val context = JavaHelpers.createJavaContext(request)
com.feth.play.module.pa.controllers.AuthenticateBase.noCache(context.response())
val filledForm = Account.PasswordChangeForm.bindFromRequest
// compilation error here, it can't see the request ^^^^^^^
if (filledForm.hasErrors) {
// User did not select whether to link or not link
BadRequest(views.html.account.password_change(userService, filledForm))
} else {
val Some(user: UserRow) = userService.getUser(context.session)
val newPassword = filledForm.get.password
userService.changePassword(user, new MyUsernamePasswordAuthUser(newPassword), true)
Redirect(routes.Application.profile).flashing(
Application.FLASH_MESSAGE_KEY -> messagesApi.preferred(request)("playauthenticate.change_password.success")
)
}
}
}
字符串
上面的实现会导致编译错误:
[error] /home/bravegag/code/play-authenticate-usage-scala/app/controllers/Account.scala:74: Cannot find any HTTP Request here
[error] val filledForm = Account.PasswordChangeForm.bindFromRequest
[error] ^
[error] one error found
型
但是,如果我将第2行从:
{ request => // <<<<<<<<<<<< here is the request
型
到
{ implicit request => // <<<<<<<<<<<< here is the request
型
然后编译,但为什么呢
2条答案
按热度按时间x759pob21#
您正在寻找的是Implicit Parameters。简而言之:
隐式参数可以像常规参数或显式参数一样传递。如果您没有显式提供隐式参数,那么编译器将尝试为您传递一个。隐式参数可以来自各种地方。来自FAQ Where does Scala look for implicits?:
1.首先查看当前范围
1.现在查看
在第1项下隐含。优先于第2项下的。
在你的例子中,通过将
request
标记为implicit
,你声明了一个“Implicit defined in current scope”。你需要有一个隐式请求,因为bindFormRequest
“要求”你传递一个请求。参见它的签名:字符串
现在你已经在作用域中有了一个
implicit request
,编译器会自动将它传递给bindFromRequest
。正如我在开始时提到的,你也可以显式地传递
request
:型
在后一种情况下,没有必要将
request
声明为implicit
,因为显然你是显式传递request
。两种变体都是相等的。你可以选择哪一种。sg2wtvxw2#
在作用域中需要一个
implicit request
,如下所示:https://github.com/pedrorijo91/play-slick3-steps/blob/master/app/controllers/ApplicationController.scala#L11