流畅的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() }
在函数内部(花括号内部)传递给apply
, this
是apply
被调用的对象,这使得可以在不写入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)