如何解决Kotlin 在构造函数中初始化变量内部函数
在 Kotlin 中,未声明为 nullable 或 lateinit 的变量必须在构造函数(或 init)中进行初始化。我正在尝试这样做:
class Foo{
var foo:myType
init{
complicatedFooInit()
}
fun complicatedFooInit(){
foo = //a whole bunch of code here
}
}
我仍然收到 Property must be initialized or declared abstract
错误。您可以通过将 myType
设为 Int
并在 complicatedFooInit
函数中将其设置为 3 来轻松重现这一点。显然有办法解决这个问题(只是不让它成为一个函数,让 complicatedFooInit
返回 myType
并将 foo 设置为等于它,等等)。我的问题是,为什么上面的代码无效?或者经过一些调整后是否有效?
解决方法
编译器不知道 complicatedFooInit()
函数内部发生了什么(因为调查从 init
块调用的潜在数十个嵌套函数的所有执行流程可能过于繁重)。他想直接在 init
块内看到初始化。所以你需要让 complicatedFooInit()
返回所需的值:
class Foo {
var foo: myType
init {
foo = complicatedFooInit()
}
fun complicatedFooInit(): myType {
//a whole bunch of code here
return ...
}
}
实际上,在这种情况下,声明站点上的属性初始化将更加简洁(根本不需要 init
块):
var foo: String = complicatedFooInit()
,
还要考虑到您可以有多个 init
块,因此如果您想将初始化的某些部分提取到一个函数中,例如
init {
complicatedFooInit()
complicatedBarInit()
}
我会用单独的 init
块替换每个函数:
// comment about foo initialization
init {
// body of complicatedFooInit()
}
// comment about bar initialization
init {
// body of complicatedBarInit()
}
问题是你不能将参数传递给 init
块;但是您传递给 complicatedFooInit
的任何参数只能依赖于主构造函数参数,因此可以在相应 init
块的开头进行设置。
你也不能用不同的参数两次调用同一个函数,
init {
complicatedFooInit(true)
complicatedFooInit(false)
}
但无论如何你都不想,因为它会初始化 foo
两次;除非 complicatedFooInit
根据其参数初始化不同的变量,但这会使 Михаил Нафталь 的回答中提到的编译器负担更糟!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。