流畅的kotlin数据类方法

我们熟悉java和其他编程语言调用方法的流畅接口。 例如:

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

这可以通过setter方法返回所需类型的对象。

 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; } 

我正在努力做同样的kotlin数据类, 但遗憾的是我找不到一种方法来重写setter方法,我可以返回该对象的新实例。

当我尝试强制覆盖setter方法时,出现编译器错误。 在这里输入图像描述

任何有关可以做什么的想法都可以调用流畅的接口,或者至少改变setter的工作方式

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

所以我可以打电话

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

如果不需要返回除Name任何内容,则可以这样做:

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

或者另一个例子:

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

在函数内部(花括号内部)传递给applythisapply被调用的对象,这使得可以在不写入name.firstName情况下引用成员函数和属性(如firstName

如果你对此不满意:不可能让实际的setter返回一些东西,但是你当然可以定义一个不同名字的方法,并返回一些东西。

为了访问Kotlin中的属性,我们不使用getter和setter函数,虽然你可以重写它们的setter来给它们定制行为,但是你不能让它们返回任何东西,因为调用它们是一个assigment,它不是一个表达式在Kotlin。 举个例子,这不起作用:

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

你可以做的是定义额外的方法来设置它们,然后返回被调用的实例。 例如:

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

请注意,如果将此方法setLastName ,则在使用Java类时会遇到问题,因为在编写Java代码时, lastName属性通过名为setLastName的方法已经可见。

Kotlin也许更常见的解决方案是用标准库中的apply来代替流利的建造者,正如Christian在答案中已经描述的那样。

感谢Zsmb13和Christin的答复,但如果有人想使用不可变的领域,我有另一种解决方案

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

你可以像这样使用它

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

输出:

 Foo(fooString=foo, fooInt=7) 
Interesting Posts