kotlin - Kotlin 使用 lambda 作为初始值设定项
问题描述
所以我有以下两难境地。这不是关于某些不起作用的问题,而是关于什么会更优雅/更好的做法以及为什么。
所以,我们知道邻接init
块,初始化逻辑进入它们。也许您打开一个文件或从配置文件中读取一些常量,也许您基于一些使用构造函数参数的更复杂的算法来设置一些属性。
但是,如果您的一个/某些属性确实需要一点逻辑,琐碎的逻辑,例如验证参数或类似的事情,该怎么办。而且这个逻辑只与那个特定的属性有关,与其他属性没有交互?
例如:
class MyCircularQueue(k: Int) {
private val arr = {
if (k < 1)
throw IllegalArgumentException("k must be at least 1")
else
Array(k) { 0 }
}()
private var head = 0
private var tail = 0
private var empty = true
}
这里arr
需要初始化为一个s的数组,但是如果小于10
显然有问题。需要一个很短的初始化逻辑,只需要简单的检查,抛出异常或者初始化数组。k
没有与其他属性的交互,没有复杂的逻辑,只是一个极其微不足道的检查或逻辑。
在这种情况下,我想知道将琐碎的初始化逻辑放在“临时”代码块(当场调用的 lambda)中是否更好。好处是声明和初始化逻辑将在同一个地方,不需要分开,我认为这种方式更具可读性。
所以在我写完这篇文章后,我想知道是否有其他人对非常简单的初始化逻辑有这个问题,但我真的找不到任何关于它的东西。
所以底线:这可以吗?是好的做法,还是至少不是坏做法?是否有意义?在 Kotlin 中是否有更好和/或官方的方法来做到这一点?
解决方案
函数变通方法不是必需的,if
是一个表达式并返回一个值,因此可以简化:
private val arr =
if (k < 1)
throw IllegalArgumentException("k must be at least 1")
else
Array(k) { 0 }
或者,Kotlin 在标准库中附带了许多功能性 API,可以帮助创建简洁的单行。在这种情况下,您可以这样做:
private val arr =
k.takeIf { it > 0 }?.let { Array(k) { 0 } } ?: throw IllegalArgumentException("k must be at least 1")