在不初始化函数的情况下声明val

时间:2020-08-25 07:41:51

标签: kotlin syntax initialization

by lazy

我了解这里发生了什么-无法重新分配val。
因此,当我需要val但无法初始化时,我曾经使用class Solution { fun love(){ val message : String message = "love" //this works message = "hate" //this is error "val cannot be reassigned" } }

message = "love"

这里我可以不用初始化就可以delcare val,以后再写代码[...]。这是怎么回事?

1 个答案:

答案 0 :(得分:0)

@deHaar正确地注意到,只有var(可变变量)适合您的情况。

您得到的错误是绝对正确的,是预期的。

这是怎么回事?

当声明一个只读变量而不初始化它时,必须确保每个执行路径在该只读变量中都有一个值。这意味着Kotlin确保在每个使用它的地方都对您的只读变量进行了初始化或未初始化,如果该变量使用不当,则会引发错误。

这里您只有一个执行路径,因为没有whenif语句可以将执行分为几个可能的路径。

class Solution {
    fun love(){
        val message : String
        message = "love"   // Kotlin knows that `message` was not yet initialized
        message = "hate"   // Kotlin knows that `message` was yet initialized! It does not allow to modify the value.
    }
}

这是Kotlin文档所说的:

...也可以(但不鼓励)拆分声明和初始赋值,甚至可以根据某些条件在多个位置进行初始化。您只能在编译器可以证明每个可能的执行路径都已将其初始化的点读取变量。如果您是以这种方式创建只读变量,则还必须确保每个可能的执行路径都只为其分配一次。

执行路径示例

使用whenif语句创建两个或更多执行路径。 执行路径可以表示为图形,我将使用#number作为节点号。示例:

class Solution {
    fun love(){
        // #1
        val message : String
        if (System.currentTimeMillisec() % 2 == 0) {
            message = "Not empty"      
            // #2
        }

        if (message.isEmpty) { // Error! Message could be not initialized at this point! 
            println("Empty message")
            // #3
        }
    }
}

看看这个没有编译的例子,我们可以计算至少3条执行路径。

  1. #1(未输入任何if语句。所有条件均为false
  2. #1->#2
  3. #1->#3

Kotlin可以计算这些路径,并检查message变量是否在使用的每个路径中均已初始化。如我们所见,一旦达到第二条if语句的评估值(在第一条路径和第三条路径的情况下),您的程序就会崩溃,因为message没有任何价值。它在内存中没有地址,并且运行此程序的计算机不知道如何从不存在的地址获取值。

现在,让我们修改此代码以使其起作用:

class Solution {
    fun love(){
        // #1
        val message : String
        if (System.currentTimeMillisec() % 2 == 0) {
            message = "Not empty"      
            // #2
        } else {
            message = ""
            // #3
        }

        if (message.isEmpty) { // Error! Message could be not initialized at this point! 
            println("Empty message")
            // #4
        }
    }
}

执行路径:

  1. #1->#2
  2. #1->#3->#4

在此示例中,Kotlin确保初始化message只读变量,因为将有100%的机会执行节点2或节点3中的一个。在message获得其初始值(已初始化)的行之后,Kotlin将此变量视为具有值的只读变量。

欢迎提问。我将尝试简化此答案。

相关问题