Kotlin中用于管理派生属性的选项

派生属性是从其他属性计算得出的属性, 例如

  • fullName是根据名字,中间名和姓氏汇总的
  • age是从出生日期算起的
  • 等等

Kotlin提供了不同的选项来管理此类派生属性。 让我们浏览它们。

内联字段初始化

管理派生属性的最简单方法是声明一个属性,并将其声明与初始化进行混合:

classPerson(valfirstName:String,
             valmiddleName:String,
             vallastName:String){

  valname="$firstName $middleName $lastName"
}

如果不需要逻辑,则效果很好。 但是,如果某些属性可为空,并且需要正确管理null值,该怎么办?

初始化块

当涉及逻辑时,使代码更具可读性要求将初始化移入专用的init块:

classPerson(valfirstName:String?=null,
             valmiddleName:String?=null,
             vallastName:String?=null){

  valname:String (1)

  init{
    valfullName="""${firstName?.let { it }}
                    | ${middleName?.let { it }}
                    | ${lastName?.let { it }}""".trimMargin() (2)
    if(fullName.isBlank())name=fullName
                       elsename="John Doe"
  }
}
  1. name是一个val ,必须初始化
  2. 初始化发生在init块中,因此编译器不会抱怨

因为该属性是val ,所以当派生属性仅依赖于常量和构造函数参数时,该方法很好。 但是,如果估值取决于其他因素(例如当前日期)怎么办?

吸气剂

例如,上述方法不能用于计算一个人的年龄,因为它不仅取决于出生日期,而且还取决于当前日期。 在Kotlin中计算此类属性的规范方法是使用专用的getter方法:

classPerson(valbirthDate:LocalDate){

  valage:Int
    get()=birthDate.until(LocalDate.now(),ChronoUnit.DAYS).toInt()
}

getter可以轻松替换内联字段初始化和init块。 但是,两者之间存在巨大的差异:getter是方法,可能不是高性能的。

如果结果需要花费时间来计算,并且不断重复返回相同的结果,则此方法不适用。

懒惰的代表

如果派生的属性,则返回值可从缓存中受益:

  1. 需要时间来计算
  2. 随着时间的推移总是返回相同的结果
  3. 并且-但不一定-需要经常访问

Kotlin提供了一种称为委托属性的构造。 要缓存结果,相关的类型是lazy委托:

classPerson(valfirstName:String,
             valmiddleName:String,
             vallastName:String){

  valnamebylazy{computeName()} (1)

  privatefuncomputeName()="$firstName $middleName $lastName" (2)
}
  1. 获取值并将其缓存
  2. 想象一下这是一个非常耗时的操作

如预期的那样, lazy使得它:

  1. 如果从未访问过该值,则不会计算
  2. 如果是,则是第一次计算并缓存
  3. 第二次访问时,该值从缓存中返回

翻译自: https://blog.frankel.ch/options-manage-derived-attributes-kotlin/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值