Return Scala 中的函数

Return function in Scala

我有以下示例代码:

def transferFiles(files: List[String], move: Boolean = false ): Unit = {
    for(file <- files) {
        if (move) {
            println(s"Move $file")
        } else {
            println(s"Copy $file")
        }
    }
}

val files = List("autoexec.bat", "config.sys")
transferFiles(files)

这将按预期打印:

Copy autoexec.bat
Copy config.sys

我想将其优化为类似于

的方式
def transferFiles(files: List[String], move: Boolean = false ): Unit = {
    def transfer = () => {
        println("Checking flag")
        if (move) {
            (file: String) => println(s"Move $file")
        } else {
            (file: String) => println(s"Copy $file")
        }       
    }
    for(file <- files) {
        transfer()(file)
    }
}

val files = List("autoexec.bat", "config.sys")
transferFiles(files)

打印:

Checking flag
Copy autoexec.bat
Checking flag
Copy config.sys

问题是我只想看到 Checking flag 一次,我不想调用带有双括号 transfer()(file) 的函数。我相信 高阶函数 可以用于此目的,但我不知道如何让它工作。是否有人能够修补我的代码,使其至少满足第一个要求(仅打印一次标志检查)?

我看到你的问题了,这个解决方案怎么样?你可以做一个简单的内部函数,在传输之前只打印一次检查。

def transferFiles(files: List[String], move: Boolean = false ): Unit = {
    def transfer(file: String): Unit = {
        if (move) {
            println("Move $file")
        } else {
            println("Copy $file")
        }       
    }
    println("Checking flag")
    for(file <- files) {
        transfer(file)
    }
}

val files = List("autoexec.bat", "config.sys")
transferFiles(files)
def transferFiles(files: List[String], move: Boolean = false ): Unit = {
    val action = if(move) {
        println("Checking flag")
        (file: String) => println(s"Move $file")
    } else {
        println("Checking flag")
        (file: String) => println(s"Copy $file")
    }
    for(file <- files)
        action(file)
}

但我会推荐这个

def transferFiles(files: List[String], move: Boolean = false ): Unit = {
    if(move) {
        println("Checking flag")
        doFiles(files, file => println(s"Move $file"))
    } else {
        println("Checking flag")
        doFiles(files, file => println(s"Copy $file"))
    }
}

def doFiles(files: List[String], action: String => Unit ): Unit = {
    for(file <- files)
        action(file)
}

def transfer 是一种没有参数的方法,returns 函数没有参数,returns 函数。您可以调用一次并将结果保存在这样的变量中:

def transfer = () => { ... }
val transferMethodResult = transfer
val transferFunctionResult = transferMethodResult()
for(file <- files) {
    transferFunctionResult(file)
}

您可以将 def transfer 替换为 val transfer,因为您不需要方法。有关详细信息,请参阅 this answer

val transfer = () => { ... }
val transferFunctionResult = transfer()
for(file <- files) {
    transferFunctionResult(file)
}

现在您拥有了 returns 实际功能的无参数功能。你不需要这个函数,你可以评估它的主体 "in place" 作为代码块来获得实际的传递函数:

val transfer = {
    println("Checking flag")
    if (move) {
        (file: String) => println(s"Move $file")
    } else {
        (file: String) => println(s"Copy $file")
    }       
}
for(file <- files) {
    transfer(file)
}

现在你有了一个代码块 ({...})。你不需要这个代码块,你需要它的结果。您可以将此代码块 ("result expression") 的最后一个表达式分配给这样的变量:

println("Checking flag")

val transfer =
    if (move) {
        (file: String) => println(s"Move $file")
    } else {
        (file: String) => println(s"Copy $file")
    }       
for(file <- files) {
    transfer(file)
}

一般来说,如果您有 val a = { expr1; expr2; ... exprN; resExpr},您可以将其替换为 expr1; expr2; ... exprN; val a = resExpr