【问题标题】:Scala pass function as argument and execute conditionallyScala将函数作为参数传递并有条件地执行
【发布时间】:2013-06-03 15:00:38
【问题描述】:

假设我有一个对象,其方法名为 protect

这应该是一个带有JValue => JValue(非泛型参数)的函数。

 def protect(func: (JValue) => JValue) = {
        if (Something.is) {
            InMemoryResponse(Array(), Nil, Nil, 200)
        } else {
            InMemoryResponse(Array(), Nil, Nil, 401)
        }
  }

我现在如何调用传递其原始参数的函数?

目标是在响应 REST 请求之前检查用户会话是否存在。如果没有,则将自动返回 401 Forbidden,如下所示。在这种情况下,我想将Users.getUsers 作为参数函数传递,并将limit 作为参数传递给函数。

所以在protect内部,如果Session存在,函数就会执行并显示出来。

serve {
    case "user" :: limit :: Nil JsonGet _ =>
        AuthorizedReq.protect(json => Users.getUsers(limit))

【问题讨论】:

  • 请不要对真/假使用模式匹配:-(简单的if就足够了
  • if (Something.is) trueCaseResult else falseCaseResult。此外,不要在 case 表达式周围加上大括号。一般来说,要避免多余的标点符号——它通常只是噪音。

标签: scala


【解决方案1】:

我最终使用了这个:

object AuthorizedReq extends Logger {
    private[this] val error: JValue = ("error" -> "Unauthorized request");
    def protect(func: (JValue) => JValue, json: JValue): JValue = {
        if (LoginSession.is) {
                new OkResponse
                func(json)
            } else {
                new UnauthorizedResponse
                error;
            }
        }
    }
}

结合:

serve {
    case "user" :: limit :: Nil JsonPost json -> _ =>
        for {
            json <- AuthorizedReq.protect(json => Users.getUsers(json), json)
        } yield json: JValue
}

如果用户未通过身份验证,则服务器以401 响应,否则执行原始函数。引入角色和领域应该很容易。

这取代了 Lift 缺乏文档的默认身份验证机制。

【讨论】:

  • 不要使用return。 (除非您远远超出了 Scala 程序员新手阶段,否则没有例外。)
【解决方案2】:

据我所知,您没有实际上将函数 Users.getUsers 作为参数传递。您正在使用limit 参数传递一个调用此函数的函数。

因为当您创建作为参数传递的匿名函数时,您还创建了一个闭包,limit 的值仍然可用于该函数(尽管您不可见)。您应该能够只调用 func 而不使用任何参数并让它正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 2011-11-02
    相关资源
    最近更新 更多