在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中,它是Iterable
, Sequence
或Array
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>
返回可为空的值(顺便说一下,是否有必要?)。
你也可以使用foldRight
, 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) } }
尝试apply{}
。 在{}
块中传递用“;”分隔的方法
Object().apply{ method1(); signUp(user) }
- 带有Java接口的Kotlin EJB抛出UndeclaredThrowableException
- Dagger2和Kotlin运行失败的原因是:app:compileDebugKotlinAfterJava
- 智能投射不能按预期工作
- Spring Web Flux(反应式)功能路由与Kotlin无法正常工作
- Java允许通过它的孩子来访问Kotlin的基本变量,但不是Kotlin,为什么?
- 当被Spring代理类访问时,Kotlin实例变量为null
- Kotlin文件不能使用R.java
- 类型不匹配,所需的节点,找到的字符串
- android.hardware.camera2全部在手机上时,但在模拟器上非常黑暗