Ser*_*aev 4 functional-programming scala
下面是执行一些URL规范化的代码片段.如何重写它只使用不可变变量?
当然,不要让它更大或更复杂.
private def normalizeUrl(url0: String) = {
var url = url0
if (url.endsWith("/")) {
url = url.dropRight(1)
}
if (url.indexOf(':') < 0 ||
url.indexOf(':') == 1) { //windows absolute path
url = "file:" + url;
}
url = url.replaceAll("\\\\", "/");
url
}
Run Code Online (Sandbox Code Playgroud)
cmb*_*ter 10
如果你想将一堆if/then条件链接起来修改一个字符串,你可以考虑添加一个隐式类来处理if/then评估,如下所示:
object UrlPimping{
implicit class PimpedUrl(val url:String) extends AnyVal{
def changeIf(condition:String => Boolean)(f:String => String):String = {
if (condition(url)) f(url)
else url
}
}
}
private def normalizeUrl(url: String) = {
import UrlPimping._
url.
changeIf(_.endsWith("/"))(_.dropRight(1)).
changeIf(u => u.indexOf(':') < 0 || u.indexOf(':') == 1)(u => s"file:$u").
replaceAll("\\\\", "/")
}
Run Code Online (Sandbox Code Playgroud)
如果你只考虑这两个条件,这将是一种过度杀伤,但如果你有更多的条件可能会很好,这是一个常见的模式.
考虑函数式编程的名称!重点是用函数替换变量.
private def normalizeProtocol(url: String) =
if (url.endsWith("/")) url.dropRight(1) else url
private def removeEndingSlash(url: String) =
if (url.indexOf(':') < 0 ||
url.indexOf(':') == 1) //windows absolute path
"file:" + url
else
url
private def replaceSlash(url: String) =
url.replaceAll("\\\\", "/");
private def normalizeUrl(url: String) =
replaceSlash(normalizeProtocol(removeEndingSlash(url)))
Run Code Online (Sandbox Code Playgroud)
CM Baxter指出,最后一个函数也可以写成
private val normalizeUrl =
removeEndingSlash _ andThen
normalizeProtocol andThen
replaceSlash
Run Code Online (Sandbox Code Playgroud)
我留给你决定哪个更清晰.