有没有办法表明函数只能由init调用?

时间:2018-02-19 05:47:12

标签: kotlin

我正在考虑初始化一些值,而不是在init函数中复杂化,我重构为一个函数,例如callSomeFunctionThatWillOnlyBeCalledByInit(),并让finalValue初始化。

val finalValue: String

init {
    callSomeFunctionThatWillOnlyBeCalledByInit()
}

fun callSomeFunctionThatWillOnlyBeCalledByInit() {
    finalValue = "Something"
}

显然它会投诉val cannot be reassigned。我清楚地知道只会在callSomeFunctionThatWillOnlyBeCalledByInit()中调用init。但有没有办法让编译器知道这一点,所以它没有投诉?

注意:

我知道我可以做如下的事情

val finalValue: String

init {
    finalValue = callSomeFunctionThatWillOnlyBeCalledByInit()
}

fun callSomeFunctionThatWillOnlyBeCalledByInit() : String {
    return "Something"
}

但我只是想探索是否有更好地重构init的方法,并且可以将初始化放在某个函数中,而不是必须在init中进行。

3 个答案:

答案 0 :(得分:6)

在kotlin中,您几乎可以在任何范围内声明函数。例如,您可以在init块中声明函数,它只能在该块中使用:

class Example { 
    val finalValue: String

    init {
        fun callSomeFunctionThatWillOnlyBeCalledByInit(): String {
            return "Something"
        }

        finalValue = callSomeFunctionThatWillOnlyBeCalledByInit()
    }
}

答案 1 :(得分:0)

SimY4的答案非常合适,但还有另外一种方法。所以,这是一个补充。

您根本不需要在init进行初始化,以实现您的目标:

class Example {

    val finalValue: String = {
        // do something complex 
        "test"
    }()
}

lambda只能在类初始化期间运行一次。之后无法调用它。

答案 2 :(得分:-1)

语言中没有单独的构造来支持这一点,您的属性必须与其声明内联或在初始化程序块内初始化。

如果您希望初始化具有分隔的部分,您可以:

  • 如果您的初始化很简单,请加入您的声明和作业,并将这些属性整理成组:

    // Strings
    val myString = "foo"
    
    // Ints
    val myInt = 256
    
  • 使用初始化程序块,只对部分进行注释:

    val myString: String
    val myInt: Int
    
    init {
        // Strings
        myString = "foo"
    
        // Ints
        myInt = 256
    }
    
  • 使用多个初始化程序块these will be executed in order from top to bottom。具有将val设置为值的单独函数将是有问题的,因为在初始化之后您可能稍后再次调用它。如果使用初始化程序块,则可以确保只调用一次。

    val myString: String
    val myInt: Int
    
    init {
        myString = "foo"
    }
    
    init {
        myInt = 256
    }