Métodos fluidos para la class de datos en kotlin

Estamos familiarizados con las interfaces fluidas para llamar a los methods en Java y otros lenguajes de progtwigción. Por ejemplo:

Picasso.with(this).load(url).into(imageView); 

Esto es posible gracias a los methods setter que devuelven el object del tipo deseado.

 public Picasso with(Context context) { this.context = context; return this; } public X load(String url) { this.url = url; return this; } public Y load(ImageView imageView) { this.imageView = imageView; return this; } 

Estoy tratando de hacer lo mismo con las classs de datos de kotlin, pero lamentablemente no pude encontrar una manera de anular los methods setter en los que podía devolver la nueva instancia de ese object.

Obtengo un error de compilation cuando bash anular forzosamente el método setter. enter image description here

Cualquier idea sobre lo que se puede hacer para que pueda llamar interfaces fluidas o al less alterar cómo funciona el colocador puede ser así

 data class CorruptOfficeAccount(.....){ override fun addCollectedFee(Long money) :CorruptOfficeAccount { this.money = money/5 } } 

Para que pueda llamar

 CorrutOfficeAccount(....).method1().addCollectedFee(20000).method3() 

    Si no necesita devolver nada más que Name , puede hacerlo así:

     data class Name(var firstName: String, var lastName: String) fun foo() { val name = ... name.apply { firstName = ... lastName = ... } } 

    u otro ejemplo:

     CorrutOfficeAccount(....).apply { method1() addCollectedFee(20000) method3() } 

    Dentro de la function (qué hay dentro de las llaves) pasada para apply , this es el object al que se apply la apply , lo que hace que sea posible referirse a funciones y properties de miembros como firstName sin escribir name.firstName .

    Si no está contento con esto: no es posible hacer que el organismo real devuelva algo, sin embargo, por supuesto, simplemente puede definir un método con un nombre diferente y hacer que devuelva algo.

    Para acceder a las properties en Kotlin, no usamos las funciones getter y setter, y aunque puede anular sus setters para darles un comportamiento personalizado, no puede hacer que devuelvan nada, porque llamarlos es una asignación, que no es una expresión en Kotlin. Como ejemplo, esto no funciona:

     var x = 1 var y = (x = 5) // "Assigments are not expressions, and only expressions are allowed in this context" 

    Lo que puede hacer es definir methods adicionales que los configuren y luego devolver la instancia en la que se invocaron. Por ejemplo:

     data class Name(var firstName: String = "", var lastName: String = "") { fun withLastName(lastName: String): Name { this.lastName = lastName return this } } val name = Name(firstName = "Jane") name.withLastName("Doe").withLastName("Carter") 

    Tenga en count que si nombra este método setLastName , tendrá problemas con el uso de la class de Java, ya que la propiedad lastName ya está visible a través de un método llamado setLastName cuando está escribiendo código Java.

    Sin embargo, la solución quizás más habitual en Kotlin es replace los constructores fluidos mediante el uso de la apply de la biblioteca estándar, como ya se describió en la respuesta de Christian.

    Gracias a Zsmb13 y Christin por la respuesta, pero si alguien quiere usar campos inmutables, tengo otra solución

     data class Foo(val fooString: String = "", val fooInt: Int = 0) { fun increaseTwo() = copy(fooInt = fooInt + 2) fun increaseThree() = copy(fooInt = fooInt + 3) } 

    Y puedes usarlo así

     println( Foo("foo",2).increaseTwo().increaseThree()) 

    Salida:

     Foo(fooString=foo, fooInt=7)