Una forma más simple o más funcional de encadenar objects en Kotlin

He creado un método auxiliar buildChain que esencialmente crea una cadena de objects dado que implementan la interfaz IChain<T> y configuran los contratos next member

El código

 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 } 

Ejemplo de implementación

 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")) 

Ejemplo de salida de implementación

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

¿Hay alguna manera functional o simpler de lograr el code anterior manteniendo el mismo uso de implementación?

Un doblez de idioma funcional se adapta bien a sus necesidades: toma un elemento inicial y luego itera sobre los otros elementos, manteniendo un valor acumulado, que se actualiza en cada elemento que se procesa con la function que usted proporciona.

En Kotlin, es la function de extensión de fold para Iterable , Sequence o Array .

Puedes usarlo de la siguiente manera:

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

Aquí first as T? se necesita molde para que el tipo de acumulador se deduzca como T? nulable T? , porque el plus en su Chain<T> devuelve un valor anulable (por cierto, ¿es necesario?).

También puedes usar foldRight , que simplemente itera en el order opuesto:

 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 } 

Y existen networkinguce y networkinguceRight con semántica similar, pero utilizando el primer y el último elemento respectivamente para el valor inicial del acumulador. Aquí está el ejemplo con networkinguceRight :

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

Prueba apply{} . En el {} bloque, pase sus methods separados por ';'

 Object().apply{ method1(); signUp(user) } 
  • Kotlin - Extensión para la class final
  • Clases de datos en Kotlin
  • Interoperabilidad de Kotlin-JS: uso de construcciones de lenguaje
  • No se puede convertir la advertencia de "tipo de plataforma de statement" de Kotlin en un error
  • La compilation de Android falla con kotlin-reflect y proguard
  • OnClick y TextView en Android Studio 3
  • function parámetro tipo coinciden problema
  • ¿Cómo hacer reference a la class Java booleana de kotlin?
  • No se puede resolver la cadena suministrada al parámetro vararg en la function de extensión
  • Por qué la class Kotlin ya no necesita abrirse en Spring Boot
  • ¿Cómo resolver esta verificación nula en el inicializador de forma segura?