Function literal with multiple implicit arguments

試著忘記壹切 提交于 2019-11-28 07:22:32

问题


How to define function literal with multiple implicit arguments in Scala? I've tried this way:

def create = authAction { (implicit request, user) ⇒ // Syntax error
  Ok(html.user.create(registrationForm))
}

but it throws compilation error.


回答1:


As stated in previous answer, you can only define a single implicit parameter for a function literal, but there is workaround.

Instead of multiple implicit arguments you can write function literal as taking multiple argument lists with one argument each. Then it is possible to mark each argument as implicit. Rewriting original snippet:

def create = authAction { implicit request ⇒ implicit user ⇒
  Ok(html.user.create(registrationForm))
}

You can call it from authAction as f(request)(user).

implicit keyword duplication is annoying, but at least it works.




回答2:


From what I can understand of the language specification, as of version 2.9.2 you can only define a single implicit parameter for anonymous functions.

E.g.

val autoappend = {implicit text:String => text ++ text}



回答3:


Just had a similar situation as you, implementing an authAction function in Play that would easily pass a user in. You can do it like lambdas did it, with currying; I ended up making my authAction function receive the RequestHeader implicitly, but pass in both request and user explicitly:

def authAction(f: (RequestHeader, User) => Result)(implicit request: RequestHeader) = {
    ...
    val authUser = loadUser(...)
    f(request, authUser)
}

And to use it:

def create = authAction { (request, user) =>
    Ok(html.user.create(registrationForm))
}



回答4:


There is no way to define an anonymous function with multiple implicit parameters.

To elaborate on @pagoda_5b's answer and @paradigmatic's comment, section 6.23 of the Scala Language Specification defines anonymous functions like so:

Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
ResultExpr ::= (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
Binding ::= (id | ‘_’) [‘:’ Type]

As you can see, you can either define a list of parameters or a single implicit parameter.

If you need multiple parameters to be implicit, you need to curry them.



来源:https://stackoverflow.com/questions/14072061/function-literal-with-multiple-implicit-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!