当我有一个将另一个函数作为参数的函数时,我可以这样称呼它:
fun foo(m: String, bar: (m: String) -> Unit) {
bar(m)
}
foo("a message") {
println("message: $it")
}
有没有一种方法可以像上面那样用一个方括号来调用它?我只知道这种方式:
fun foo(m: String, bar1: (m: String) -> Unit, bar2: (m: String) -> Unit) {
bar1(m)
bar2(m)
}
foo("a message", { println("message 1: $it") }, { println("message 2: $it") } )
答案 0 :(得分:1)
只是为了好玩...这里有一些尝试来获得与您所要求的相似的东西。请注意,除了“标准”方法,我不能真正推荐其他方法;-)(即免责声明)
原样为
fun method1(s: String,
m1: (String) -> String,
m2: (String) -> String) {
println(m1(s))
println(m2(s))
}
method1("test", { "m1: $it" }) {
"m2: $it"
}
// if you like with or without mentioning the parameter names:
method1("test",
m1 = { "m1: $it" },
m2 = { "m2: $it" }
)
// 1b. using own methods and supplying method references
fun m1(s : String) = "m1: $s"
fun m2(s : String) = "m2: $s"
method1("test1b", ::m1 /*, ::m2 */) {
"m2: $it"
}
使用invoke ...
class Method2(val s: String,
val m1: (String) -> String) {
operator fun invoke(m2: (String) -> String) {
println(m1(s))
println(m2(s))
}
}
fun method2(s: String,
m1: (String) -> String) = Method2(s, m1)
method2("test2") {
"m1: $it"
}() {
"m2: $it"
}
使用具有自身丑陋扩展功能的配对供应商
fun method3(s: String,
m1AndM2: () -> Pair<(String) -> String, (String) -> String>) {
m1AndM2().let { (m1, m2) ->
println(m1(s))
println(m2(s))
}
}
infix fun <T : (String) -> String> T.and(m2: (String) -> String) = Pair(this, m2)
method3("test3") {
{ s: String -> "m1: $s" } and // note: the "s: String" is mandatory as the compiler can not infer the type
{ "m2: $it" }
}
// 3b. using a div operator as delimiter (still a hack):
operator fun <T : (String) -> String> T.div(m2: (String) -> String) = Pair(this, m2)
method3("test3b") {
{ s: String -> "m1: $s" } / {
"m2: $it"
}
}
注意:您甚至可以使用一种解决方案,甚至可以提出更好的解决方案。我仍然会坚持第一个变体...也许方法参考在您的情况下会更有帮助。我什至发现带有命名参数的变体更好,然后尝试完成诸如块链之类的事情。而且请不要忘记:其他人(可能更重要的是您将来的自己)应该仍然可以阅读代码;-)
答案 1 :(得分:0)
您可以使用方法引用。下面的示例使用“静态”函数,很酷的事情是您也可以引用“实例函数”(闭包):
object Xxx {
@JvmStatic
fun main(args: Array<String>) {
service("initial", ::toUpperCase, ::withSuffix)
}
fun toUpperCase(s: String) = s.toUpperCase()
fun withSuffix(s: String) = "$s.mySuffix"
fun service(argument: String, vararg enhancers: (String) -> String) {
println(enhancers.fold(argument) { s, e -> e(s) })
}
}
答案 2 :(得分:0)
我试图返回一个以另一个函数为参数的函数,以查看是否可以在()
之外获得两个lambda。
fun foo(m:String,bar1:(m:String)->Unit) : (bar2:(m:String)->Unit)->Unit
{
bar1(m)
return { bar2: (m: String) -> Unit -> bar2(m) }
}
结果证明我不能。我最后在第一个函数前后加上了一对()
,以便编译器知道最后一个lambda是返回函数的参数,而不是假定尝试在括号内的参数列表之外传递两个lambda表达式。 / p>
(foo("a message"){println("message 1: $it")}){println("message 2: $it")}
或
foo("a message"){println("message 1: $it")}(){println("message 2: $it")}
显然,这些看起来没有任何改善。我认为
foo("a message", { println("message 1: $it") }, { println("message 2: $it") } )
或
foo("a message", { println("message 1: $it") }){ println("message 2: $it")}
足够好。
有趣的是,这在Swift中是允许的
func foo (m:String,bar1 : ((String) -> Void) ) -> (_:((String) -> Void))->Void
{
bar1(m)
return {bar2 in bar2(m)}
}
foo(m: "test"){print("m1: \($0)")}{print("m2: \($0)")}