Kotlin by lazy throws NullPointerException



我目前正试图借助这本书来学习Kotlin"Kotlin编程The Big Nerd牧场指南";到目前为止一切顺利。但现在我正在与";懒惰;初始化,抛出一个NullPointerException,表示

无法调用"科特林。Lazy.getValue(("因为"<local1>quot;为空

对应的行是:

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

如果你想自己编译它,或者需要更多的代码来更好地理解它,我在下面提供Game.kt和Player.kt。如果";懒惰;被丢弃为"0";正常的";初始化家乡将按预期分配。任何解决问题和了解问题原因的技巧都是受欢迎的。

// 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块,并尝试访问name
  3. name的getter尝试读取hometown属性,但由于hometown仍未初始化而失败
  4. 。。。如果一切顺利,hometown属性现在将使用惰性委托进行初始化

因此,基本上您是在配置惰性委托之前尝试访问hometown。如果将hometown的声明移到init块的上方,则应该可以了。

你可以在操场上看到正在进行的修复

相关内容

  • 没有找到相关文章

最新更新