繁体   English   中英

如何使用带有命名参数和默认值的自定义设置器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM