【问题标题】:Function literal with multiple implicit arguments具有多个隐式参数的函数文字
【发布时间】:2012-12-13 20:51:59
【问题描述】:

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

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

但它会引发编译错误。

【问题讨论】:

  • 您能否详细说明您的代码的上下文,或者提供一个更独立的示例?这样可以更轻松地检查您的案例有什么问题。我不知道现在在哪里定义了 authActionOkhtml。您使用的是 Play! 还是 Lift 或其他东西?谢谢
  • 是的,我来自 Play 应用程序的 sn-p,它工作正常,但使用两个参数隐式代码会更清晰。

标签: function scala syntax arguments syntax-error


【解决方案1】:

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

例如

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

【讨论】:

  • 有人知道为什么会这样吗?似乎有点武断。
【解决方案2】:

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

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

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

您可以将其从authAction 调用为f(request)(user)

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

【讨论】:

    【解决方案3】:

    刚刚遇到了和你类似的情况,在 Play 中实现了一个 authAction 函数,可以很容易地传递一个用户。你可以像lambdas did it那样做,用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))
    }
    

    【讨论】:

      【解决方案4】:

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

      为了详细说明@pagoda_5b 的回答和@paradigmatic 的评论,Scala Language Specification 的第 6.23 节定义了匿名函数,如下所示:

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

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

      如果你需要多个参数是隐式的,你需要柯里化它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多