【问题标题】:scala: how to rewrite this function using for comprehensionscala:如何使用 for comprehension 重写此函数
【发布时间】:2012-10-31 00:57:59
【问题描述】:

我的这段代码带有几个讨厌的嵌套检查...

我很确定它可以重写为便于理解,但我对如何混合模式匹配的东西有点困惑

// first tries to find the token in a header: "authorization: ideas_token=xxxxx"
// then tries to find the token in the querystring: "ideas_token=xxxxx"
private def applicationTokenFromRequest(request: Request[AnyContent]): Option[String] = {

  val fromHeaders: Option[String] = request.headers.get("authorization")
  val tokenRegExp = """^\s*ideas_token\s*=\s*(\w+)\s*$""".r

  val tokenFromHeader: Option[String] = {
    if (fromHeaders.isDefined) {
      val header = fromHeaders.get
      if (tokenRegExp.pattern.matcher(header).matches) {
        val tokenRegExp(extracted) = header
        Some(extracted)
      } else {
        None
      }
    } else {
      None
    }
  }

  // try to find it in the queryString
  tokenFromHeader.orElse {
    request.queryString.get("ideas_token")
  }

}

你能给我什么提示吗?

【问题讨论】:

  • 在代码审查网站上可能更好
  • @NoelM:这个问题需要具体的建议,而不仅仅是代码审查。

标签: scala for-comprehension


【解决方案1】:

您只需在for-comprehension 中使用提取器即可摆脱很多麻烦:

val Token = """^\s*ideas_token\s*=\s*(\w+)\s*$""".r

val tokenFromHeader = for {
  Token(t) <- request.headers.get("authorization")
} yield t

tokenFromHeader orElse request.queryString.get("ideas_token")

但在我看来,以下内容更加简洁明了:

val Token = """^\s*ideas_token\s*=\s*(\w+)\s*$""".r

request.headers.get("authorization") collect {
  case Token(t) => t
} orElse request.queryString.get("ideas_token")

不过,这两者本质上是等价的——在这两种情况下,您只需将值(如果存在)从 Option 中提取出来并查看它是否与正则表达式匹配。

【讨论】:

  • 谢谢 travis,问一个问题,像 Classes 这样的大写 reg exp 的风格好吗???
  • @opensas:在这种情况下它曾经是必要的(在 2.8 之前,我相信),是的,我个人认为当您使用 Regex 作为提取器时这是一种很好的风格(我是not the only one)。
猜你喜欢
  • 1970-01-01
  • 2014-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 2015-12-30
  • 1970-01-01
相关资源
最近更新 更多