我有一些代码与几个讨厌的嵌套检查…
我很确定它可以用一个很好的理解来重写,但我对如何混合模式匹配的东西有点困惑
// 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") } }
你能给我什么暗示吗?
解决方法
只需使用提取器进行理解,就可以摆脱很多困难:
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并查看它是否与正则表达式匹配.