如何将 lambda 链接到 Kotlin 中的结果 lambda?

How to chain lambdas to a resulting lambda in Kotlin?

... 或等同于 java.util.Function.andThen()

在Java

Function<String, String> add1 = string -> string + "1";
Function<String, String> add2 = string -> string + "2";
Function<String, Strint> add12 = add1.andThen(add2);

add12.apply("") returns "12"

我如何用 Kotlin 编写它?

val add1 = { string:String -> string + "1" }
val add2 = { string:String -> string + "2" }
val add12 = ?

您正在寻找的功能称为函数组合。据我所知,它不是内置于 Kotlin 中的(很乐意对此进行更正)。但是作为扩展函数写起来非常容易

infix fun<A, B, C> ((B) -> C).compose(that: (A) -> B): (A) -> C =
  { this(that(it)) }

现在我们可以写了

val add1 = { string:String -> string + "1" }
val add2 = { string:String -> string + "2" }

println((add2 compose add1)("3")) // Prints "312"

我写compose是为了使用从右到左的构图,更符合数学函数的工作方式。

当然,这不是您要查找的内容,因为您不能以这种方式将组合函数存储在变量中,但您可以使用 run 链接函数的结果,如果函数自己没有参数作为接收者:

fun print(string: String) {
    println(add1(string).run(add2))
}

// or

fun print(string: String) {
    println(string.run(add1).run(add2))
}

由于 run 是一个内联函数,它不会在每个函数周围添加一个包装对象。

let 函数将具有完全相同的效果。这是因为当你将 lambda 以外的东西传递给高阶函数时,第一个参数是否是接收者并不重要。它们被视为相同的签名。

如果您非常熟悉 Java 函数 and/or 想要使用它们,您仍然愿意这样做(使用 java.util.function.Function):

val add1 : Function<String, String> = Function { "${it}1"}
val add2 : Function<String, String> = Function { "${it}2"}
val add12: Function<String, String> = add1.andThen(add2)

如果我想在 Kotlin 中有类似的东西,我可能会选择 Tenfour04 也显示的内容,即使用 letrun:

val add1 : (String) -> String = { "${it}1"}
val add2 : (String) -> String = { "${it}2"}
val add12 : (String) -> String = { it.let(add1).let(add2) } // or: { add1(it).let(add2) }

如果你比较两者你只剩下一些东西,如果你省略了类型,但它仍然足够清楚组成什么。

当然,您可以实现自己的 composeandThen 功能。但是,如果您不介意使用额外的库,您可能会对 Arrow 感兴趣,其中已经支持许多功能用例。