[英]How to have a custom setter with a named argument and default
我有一个Kotlin类,带有命名参数和未指定参数的默认值。 我正在尝试找出如何为一个参数创建自定义设置器的方法,尽管似乎很简单,但似乎无法弄清楚我在做什么错。 这是该类的简化版本:
class ItemObject(var itemNumber: String = "",
var itemQty: Int = 0)
我可以使用此类的属性,而不会出现itemObject.itemQty = itemObject.itemQty + 1(同时访问getter和setter)的情况。
但是,我想进行自定义设置,以防止itemQty降至零以下。 因此,我尝试了以下主题的多种变体:
class ItemObject(var itemNumber: String = "",
itemQty: Int = 0) {
var itemQty: Int = 0
set(value: Int) =
if (value >= 0) {
itemQty = value // Don't want to go negative
} else {
}
}
这可以毫无问题地进行编译,但是似乎将itemQty的默认值保持为零(或者类似的东西-我没有找到它)。
谁能指出我正确的方向? 我当然会很感激-这是我的第一个Kotlin项目,可能需要一些帮助。 :)
这是vetoable
目的:
var quantity: Int by Delegates.vetoable(0) { _, _, new ->
new >= 0
}
返回true
接受该值,返回false
拒绝该值。
好吧,您将实数字段初始化为0并忽略了传递的值...相反,请使用传递的构造函数参数初始化属性:
class Item(_itemQty: Int = 0) {
var itemQty: Int = Math.max(0, _itemQty)
set(v) { field = Math.max(0, v) }
}
(我使用了两个不同的标识符来分隔参数和属性,如注释中所述,您也可以为属性和参数使用相同的名称[但要小心,这可能会增加混乱)。)
您还应该设置支持字段 ,而不是设置器本身,否则将以无休止的递归结束。
如果设置器非常复杂,并且还需要将其应用于初始值,则可以初始化属性,然后使用参数执行设置器:
class Item(_itemQty: Int = 0) {
var itemQty: Int = 0
set(v) { field = Math.max(0, v) }
init { itemQty = _itemQty }
}
作为基于意见的item.itemQty
说明, item.itemQty
并不是真正的描述性项目, item.quantity
更具可读性。
有多种防止值低于零的方法。 一种是无符号类型。 目前处于实验阶段。 您的情况下的UInt
class ItemObject(var itemNumber: String = "",
var itemQty: UInt = 0u
)
如果您不在乎价值溢出,则可以选择
另一种方法是财产委托
class ItemObject(var itemNumber: String = "", itemQty: Int = 0) {
var itemQty: Int by PositiveDelegate(itemQty)
}
class PositiveDelegate(private var prop: Int) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): Int = prop
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
if (value >= 0) prop = value
}
}
其他答案中介绍了带有自定义设置器的第三个选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.