9

如何在Scala中定义具有多个隐式参数的函数文字?我试过这样:

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

但它会引发编译错误。

4

4 回答 4

17

如上一个答案所述,您只能为函数文字定义一个隐式参数,但有解决方法。

您可以将函数文字编写为采用多个参数列表,每个列表带有一个参数,而不是多个隐式参数。然后可以将每个参数标记为隐式。重写原始片段:

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

您可以从authActionas调用它f(request)(user)

implicit关键字重复很烦人,但至少它有效。

于 2012-12-29T05:37:07.010 回答
6

根据我对语言规范的理解,从 2.9.2 版开始,您只能为匿名函数定义一个隐式参数。

例如

val autoappend = {implicit text:String => text ++ text}
于 2012-12-28T17:14:06.937 回答
0

刚刚遇到了与您类似的情况,在 Play 中实现了一个 authAction 函数,该函数可以轻松地将用户传入。您可以像lambdas 那样使用currying;我最终让我的authAction函数RequestHeader隐式接收,但显式传递请求和用户:

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

并使用它:

def create = authAction { (request, user) =>
    Ok(html.user.create(registrationForm))
}
于 2015-04-06T17:28:10.313 回答
0

无法定义具有多个隐式参数的匿名函数。

为了详细说明@pagoda_5b 的答案和@paradigmatic 的评论,Scala 语言规范的第 6.23 节定义了匿名函数,如下所示:

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

如您所见,您可以定义参数列表单个隐式参数。

如果需要隐式多个参数,则需要对它们进行柯里化。

于 2017-04-19T23:24:27.387 回答