在Kotlin中链接对象更简单或更实用

我创建了一个辅助方法buildChain ,它基本上创建了一个对象链,因为它们实现了接口IChain<T>并设置了合约的next成员

代码

 interface Chain<T> { var next: T? operator fun plus(next: T): T? } fun <T : Chain<T>> buildChain(first: T, vararg members: T): T { var next: T? = null members.forEachIndexed { i, t -> if (i == 0) { next = first + t } else { next = next?.run { this + t } } } return first } 

实现的例子

 data class Person(val name: String) : Chain<Person> { override var next: Person? = null override fun plus(next: Person): Person? { this.next = next return next } } fun createPersonChain() = buildChain(Person("Bob"), Person("Bitzy"), Person("Blitzy")) 

实现输出的例子

 @JvmStatic fun main(args: Array<String>) { var first = createPersonChain() // first.name = "Bob" // first.next.name = "Bitzy" // first.next.next.name = "Blitzy" } 

是否有一个functional simpler方法来实现上面的code ,保持实现的使用相同?

一个功能性的习惯折叠很适合你的需求:它需要一个初始的项目,然后迭代其他项目,保持一个累积的值,这是更新每个项目正在处理您提供的功能。

在Kotlin中,它是IterableSequenceArray fold扩展函数 。

您可以通过以下方式使用它:

 fun <T : Chain<T>> buildChain(first: T, vararg members: T): T { members.fold(first as T?) { acc, i -> acc?.let { it + i } } return first } 

这里first as T? 需要将累加器类型推断为可空T? ,因为你的Chain<T>返回可为空的值(顺便说一下,是否有必要?)。

你也可以使用foldRightfoldRight是以相反的顺序迭代:

 fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? = (listOf(first) + members) .foldRight(null as T?) { i, acc -> acc?.let { i + acc }; i } 

有相似语义的reducereduceRight ,但分别使用累加器初始值的第一项和最后一项。 以下是reduceRight的示例:

 fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? = (listOf(first) + members).reduceRight { i, acc -> i.apply { plus(acc) } } 

尝试apply{} 。 在{}块中传递用“;”分隔的方法

 Object().apply{ method1(); signUp(user) }