具有多个参数的Kotlin`with`

时间:2019-07-19 13:01:46

标签: kotlin

我非常喜欢with的举止。是否可以扩展with使其适用于多个参数。

我想这样使用with

with(foo, bar){
    fooFunction()
    barFunction()
}

4 个答案:

答案 0 :(得分:1)

首先,我坚决反对。

一个可以接近您想要的东西

data class A(val a: Int)
data class B(val b: Int)

fun<S, T> withPair(a: S, b: T, f: S.() -> T.() -> Unit) {
    val g = a.f()
    b.g()
}

fun main() {
    withPair(A(1), B(2)) {{
        print(a)
        print(b)
    }}
}

因此您可以拥有一个返回一个块函数的块函数。不过,您需要嵌套的lambda。

答案 1 :(得分:0)

我认为不可能编写像这样的函数,但是使用标准with,您可以编写

with(foo) {
    with(bar) {
        fooFunction()
        barFunction()
    }
}

(请注意,如果foobar上都可以使用一种方法,则将以这种方式调用bar方法)。

答案 2 :(得分:0)

另一种可能性是使用Pair,例如:

with( Pair("abc" , listOf(1,2,3)) ) {
    println(first.plus("d"))
    println(second.reversed())
}

打印:

abcd    [3,2,1]

答案 3 :(得分:0)

使用标准的with函数是不可能的,因为它不能具有两种接收器类型的lambda(由this访问)。

with(foo, bar){
    fooFunction() //`this` would have to mean `foo`
    barFunction() //`this` would have to mean `bar`
}

嵌套两个with很讨厌。 this可能会引起各种问题……


也就是说,您可以创建自己的with函数,该函数的工作方式与标准函数类似,但是不会使用传递的扩展名乐趣(因此,this后面的接收者类型都不会“隐藏”),但是具有两个参数的常规lambda:

inline fun <T1, T2, R> with(t1: T1, t2: T2, block: (T1, T2) -> R): R {
    return block.invoke(t1, t2)
}

//then:
with(foo, bar) { f, b ->
    f.fooFunction()
    b.barFunction()
}