gpt4 book ai didi

懒惰的 Kotlin 抛出 NullPointerException

转载 作者:行者123 更新时间:2023-12-05 01:07:06 27 4
gpt4 key购买 nike

我目前正在尝试借助“Kotlin Programming The Big Nerd Ranch Guide”一书来学习 Kotlin,到目前为止一切正常。但是现在我正在为“懒惰”的初始化而苦苦挣扎,它会抛出一个 NullPointerException,它说

Cannot invoke "kotlin.Lazy.getValue()" because "< local1>" is null

对应的行是:

val hometown by lazy { selectHometown() } 
private fun selectHometown(): String = File("data/towns.txt").readText().split("\n").shuffled().first()

如果您想自己编译或需要更多代码以便更好地理解,我会在下面提供 Game.kt 和 Player.kt。如果为“正常”初始化而放弃“懒惰”,则家乡将按预期分配。欢迎提供任何解决问题和了解问题原因的提示。

// Game.kt
package com.bignerdranch.nyethack

fun main(args: Array<String>) {

val player = Player("Madrigal")
player.castFireball()
}

private fun printPlayerStatus(player: Player) {
println("(Aura: ${player.auraColor()}) " + "(Blessed: ${if (player.isBlessed) "YES" else "NO"})")
println("${player.name} ${player.formatHealthStatus()}")
}
// Player.kt
package com.bignerdranch.nyethack

import java.io.File

class Player(_name: String, var healthPoints: Int = 100, val isBlessed: Boolean, private val isImmortal: Boolean) {


var name = _name
get() = "${field.capitalize()} of $hometown"
private set(value) {
field = value.trim()
}

constructor(name: String) : this(name, isBlessed = true, isImmortal = false) {
if (name.toLowerCase() == "kar") healthPoints = 40
}

init {
require(healthPoints > 0, { "healthPoints must be greater than zero." })
require(name.isNotBlank(), { "Player must have a name" })
}

val hometown by lazy { selectHometown() }

private fun selectHometown(): String = File("data/towns.txt").readText().split("\n").shuffled().first()

fun castFireball(numFireballs: Int = 2) =
println("A glass of Fireball springs into existence. (x$numFireballs)")


fun auraColor(): String {
val auraVisible = isBlessed && healthPoints > 60 || isImmortal
return if (auraVisible) "GREEN" else "NONE"
}
fun formatHealthStatus() =
when (healthPoints) {
100 -> "is an excellent condition!"
in 90..99 -> "has a few scratches."
in 75..89 -> if (isBlessed) {
"has some minor wounds but is healing quite quickly"
} else {
"has some minor wounds"
}
in 15..74 -> "looks pretty hurt"
else -> "is in awful condition!"
}

}

我忘记了 towns.txt 所以就在这里(不是很重要)

Neversummer
Abelhaven
Phandoril
Tampa
Sanorith
Trell
Zan'tro
Hermi Hermi
Curlthistle Forest

最佳答案

当发生这种情况时,通常是由于初始化顺序错误。

Player类的初始化是这样进行的:

  1. name 属性的支持字段使用 _name 值初始化
  2. 运行 init block ,并尝试访问 name
  3. name 的 getter 尝试读取 hometown 属性,但由于 hometown 仍未初始化而失败
  4. ...如果一切顺利,hometown 属性现在将使用惰性委托(delegate)进行初始化

所以基本上你是在配置惰性委托(delegate)之前尝试访问 hometown 。如果你把 hometown 的声明移到 init block 上面,应该没问题。

您可以看到修复的实际效果 on the playground

关于懒惰的 Kotlin 抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67890451/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com