[英]Kotlin Initialize Variable Inside Function in Constructor
In Kotlin variables not declared as nullable or lateinit must be initialized in the constructor (or init).在 Kotlin 中,未声明为 nullable 或 lateinit 的变量必须在构造函数(或 init)中初始化。 I am trying to do this like this:
我正在尝试这样做:
class Foo{
var foo:myType
init{
complicatedFooInit()
}
fun complicatedFooInit(){
foo = //a whole bunch of code here
}
}
I still get the Property must be initialized or declared abstract
error.我仍然得到
Property must be initialized or declared abstract
错误。 You can easily reproduce this by making myType
an Int
and just setting it equal to 3 in the complicatedFooInit
function.您可以通过将
myType
设置为Int
并在complicatedFooInit
function 中将其设置为 3 来轻松重现这一点。 Obviously there are ways around this (just not making it a function, having complicatedFooInit
return myType
and setting foo equal to it, etc.).显然有办法解决这个问题(只是不让它成为 function,让
complicatedFooInit
返回myType
并将 foo 设置为等于它,等等)。 My question is, why is the above code invalid?我的问题是,为什么上面的代码无效? Or is it valid with some tweaking?
或者通过一些调整是否有效?
Compiler have no idea what's going on inside complicatedFooInit()
function (cause it may be too burden to investigate all execution flow of potentially dozens nested functions called from init
block).编译器不知道 complexFooInit(
complicatedFooInit()
function 内部发生了什么(因为调查从init
块调用的可能数十个嵌套函数的所有执行流程可能负担过重)。 He wants to see initialization directly inside init
block.他想直接在
init
块中查看初始化。 So you need to make complicatedFooInit()
return desired value:所以你需要让
complicatedFooInit()
返回所需的值:
class Foo {
var foo: myType
init {
foo = complicatedFooInit()
}
fun complicatedFooInit(): myType {
//a whole bunch of code here
return ...
}
}
Actually, in this case property initialization on declaration site will be more concise (no need for init
block at all):实际上,在这种情况下,声明站点上的属性初始化会更简洁(根本不需要
init
块):
var foo: String = complicatedFooInit()
Consider also that you can have multiple init
blocks, so if you want to extract some part of initialization into a function, eg还要考虑你可以有多个
init
块,所以如果你想将初始化的某些部分提取到 function 中,例如
init {
complicatedFooInit()
complicatedBarInit()
}
I would replace each function by a separate init
block:我会用一个单独的
init
块替换每个 function :
// comment about foo initialization
init {
// body of complicatedFooInit()
}
// comment about bar initialization
init {
// body of complicatedBarInit()
}
The problem is that you can't pass arguments to init
blocks;问题是您不能将 arguments 传递给
init
块; but any arguments you'd pass to complicatedFooInit
can only depend on the primary constructor parameters, and so can be set up in the beginning of the corresponding init
block.但是您传递给
complicatedFooInit
的任何 arguments 只能依赖于主构造函数参数,因此可以在相应init
块的开头进行设置。
You also can't call the same function twice with different parameters,您也不能使用不同的参数两次调用相同的 function,
init {
complicatedFooInit(true)
complicatedFooInit(false)
}
but you wouldn't want to anyway, because it would initialize foo
twice;但无论如何你都不想这样做,因为它会初始化
foo
两次; unless complicatedFooInit
initializes different variables depending on its arguments, but it would make the compiler's burden mentioned in Михаил Нафталь's answer much worse!除非
complicatedFooInit
根据其 arguments 初始化不同的变量,但这会使Михаил Нафталь 的答案中提到的编译器负担更糟!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.