我创建了一个辅助方法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
保持实施用途相同的方式?
答案 0 :(得分:9)
功能idiom fold非常适合您的需求:它接受一个初始项目,然后迭代其他项目,维护一个累计值,该值在您使用您提供的功能处理的每个项目上更新。
在Kotlin中,Iterable
,Sequence
或Array
为fold
extension function。
您可以通过以下方式使用它:
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?
,因为plus
中的Chain<T>
会返回可为空的值(顺便说一句,是吗?必要?)。
您也可以使用foldRight
,它只是以相反的顺序迭代:
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 }
并且reduce
和reduceRight
具有相似的语义,但分别使用第一个和最后一个项作为累加器的初始值。以下是reduceRight
的示例:
fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? =
(listOf(first) + members).reduceRight { i, acc -> i.apply { plus(acc) } }
答案 1 :(得分:2)
试试apply{}
。在{}
块传递中,您的方法用&#39;;&#39;
Object().apply{ method1(); signUp(user) }