如何创建一个“forEach”,它返回一个作为消费函数接收器的对象?

时间:2017-12-10 11:36:38

标签: kotlin

我正试图在一连串的“流”操作中做这样的事情。

fun main(args: Array<String>) {
    "test1, test2, test3".split(", ")
            .toCustomString(StringBuilder(), StringBuilder::append)
}

fun <T, R>Iterable<T>.toCustomString(obj: R, thing: R.(T) -> Unit): R {
    this.forEach {
        obj.thing(it)
    }
    return obj
}

但这不起作用,它表示StringBuilder::append找不到任何功能都不能应用于此处。有没有办法可以做出像这样的工作?

3 个答案:

答案 0 :(得分:2)

您正尝试使用具有不同签名的方法引用作为接收器函数。您可以使用它来提供lambda。或者正如其他答案所指出的那样,更改接收器功能的签名。

fun main(args: Array<String>) {
    "test1, test2, test3".split(", ")
            .toCustomString(StringBuilder(), { item -> append(item) })
}

答案 1 :(得分:1)

在这种情况下使用方法引用没有问题,它应该可以正常工作。

请确保您使用kotlin class StringBuilder进行更改:

fun <T, R>Iterable<T>.toCustomString(obj: R, thing: R.(T) -> Unit)

这一个:

fun <T, R>Iterable<T>.toCustomString(obj: R, thing: R.(T) -> R)

答案 2 :(得分:1)

要将StringBuilder::append用作函数引用,thing应该使用R.(T) -> R而不是R.(T) -> Unit,因为StringBuilder.append(String)将返回StringBuilder 。但是,由于toCustomString无法处理来自StringBuilder.append的返回值,因此@Marko建议更合适。

FYR,这是另一种没有额外扩展功能的方法:

val customString = StringBuilder().apply {
    "test1, test2, test3"
            .split(", ")
            .forEach { this.append(it) }
}