Kotlin 在构造函数中初始化变量内部函数
Kotlin Initialize Variable Inside Function in Constructor
在 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
return myType
和设置 foo 等于它,等等)。我的问题是,为什么上面的代码无效?或者经过一些调整是否有效?
编译器不知道 complicatedFooInit()
函数内部发生了什么(因为调查从 init
块调用的潜在数十个嵌套函数的所有执行流程可能负担过重)。他想直接在 init
块中查看初始化。所以你需要使 complicatedFooInit()
return 期望值:
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
两次; unless complicatedFooInit
根据其参数初始化不同的变量,但这会使 Михаил Нафталь 的回答中提到的编译器负担更糟!
在 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
return myType
和设置 foo 等于它,等等)。我的问题是,为什么上面的代码无效?或者经过一些调整是否有效?
编译器不知道 complicatedFooInit()
函数内部发生了什么(因为调查从 init
块调用的潜在数十个嵌套函数的所有执行流程可能负担过重)。他想直接在 init
块中查看初始化。所以你需要使 complicatedFooInit()
return 期望值:
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
两次; unless complicatedFooInit
根据其参数初始化不同的变量,但这会使 Михаил Нафталь 的回答中提到的编译器负担更糟!