通过函数Kotlin为变量赋值

eqoofvh9  于 2022-11-16  发布在  Kotlin
关注(0)|答案(1)|浏览(262)

当通过函数构造函数fun funname()创建一个变量时(它们是这样被调用的吗?),它们似乎被声明为vals。由于vals不能被重新赋值(出于某些原因,我需要这样做),我想知道是否有一种方法可以在函数之前的一行代码中将变量声明为var,然后通过函数赋值。
请记住,我昨天才开始学习Kotlin。我对所有的选择都持开放态度。
public fun singlebattle(enemyhealth : Int, enemyattack : Int , enemyname : String)
当我试图重新分配敌人的健康,我得到错误“无法重新分配瓦尔”,所以我试图声明enemyhealth和其他为vars .
错误显示在此处:enemyhealth = enemyhealth - playerstats[1]
当我用玩家伤害减去enemyhealth来显示玩家受到攻击时
我使用的是Repl.itKotlin版本1.3.72

wljmcqd8

wljmcqd81#

  • 好吧,这结束了相当长,但我希望它至少有帮助!*

这不是一个 constructor,因为它不是在构造一个对象--它只是一个函数定义,当你用singleBattle()调用这个函数时,你需要把列出的参数放在括号里。
首先,传入函数的参数在函数块中变成了本地的val--它们是只读的。你可以用它们做一些事情,然后把结果赋给你在函数中声明的另一个valvar
但我假设你实际上是想做的事情是这样的:

  • A可以访问finalBossHealth之类的变量
  • A将finalBossHealth传递给函数B(作为enemyhealth
  • B改变enemyHealth的值
  • A看到finalBossHealth中的变化,因为它是“相同的变量”

你不能这么做,因为你的参数是固定的val。你基本上有两个选择:

  • 在函数外部定义变量,A和B都可以看到这些变量 *

只要函数与变量(字段)在同一个类中,它就在同一个 * 作用域 * 中,并且可以直接修改它们。在这种情况下,传入该值没有真实的意义,因为它可以直接读写它们

var enemyHealth = 9999

public fun singleBattle() {
    enemyHealth = enemyHealth - 100
}

在实践中,你可能有一个敌人列表或者其他什么东西,你会传入一个索引,这样函数就可以查找并修改它。

  • 返回A要使用的更新值 *

这就是函数式方法--你传入某些数据,函数对它做一些事情,然后把结果传出去。理想情况下,如果你传入相同的数据,你每次都得到完全相同的结果--所以它只依赖于参数,而不是函数之外的任何状态如果它在类之外没有任何副作用(比如改变类中的var),那么它就被称为 pure 函数。
这些都是很容易的原因,因为他们只是做一件事-把价值观,得到具体的结果,容易!

public fun singlebattle(enemyhealth : Int, enemyattack : Int , enemyname : String): Int {
    // calculate whatever
    return updatedHealth;
}

这个函数只返回一个Int,因此调用者将调用singleBattle,然后对结果执行一些操作。singleBattle不需要知道任何有关外部状态的信息,它只需要获取一些值并对它们执行一些有用的操作。
如果你需要返回不止一个值(比如说攻击可以减少),你可以创建某种数据结构来保存一堆值:

data class Fighter(val health: Int, val attack: Int, val name: String)

public fun singlebattle(player: Fighter, enemy: Fighter): Fighter {
    // calculate the player's state after the fight
    return player.copy(health = newHealth)
    // or just return Fighter(newHealth, player.attack, player.name)...
}

如果你想返回多个Fighter(这样你也有更新的敌人状态),你可能想使用另一个同时包含它们的对象,比如data class Battle(val fighter1: Fighter, fighter2: Fighter)
你可以通过将引用传递给函数的方式,将这些方法结合起来(这样会失去纯函数的优点,但这样做可能会更容易):

// I'm using vars here because we're gonna change them
data class Fighter(var health: Int, var attack: Int)

val player = Fighter(100, 999)
val monster1 = Fighter(9999, 5)

singleBattle(player, monster1)

fun singleBattle(fighter1: Fighter, fighter2: Fighter) {
    // do the fight, update the values
    fighter1.health = fighter1.health - fighter2.attack
    // etc... you can also say fighter1 -= fighter2.attack as a shorthand
}

这个函数不返回任何东西,因为它只是改变了那些传入的Fighter对象中的变量。传入的调用引用了playermonster1对象,而不是新的副本,尽管你不能改变fighter1的值(例如,它引用了哪个Fighter对象),您可以在该对象内部四处查看。(有对它的引用)将看到更新。因此,在调用singleBattle(player, monster1)之后,您将看到player1.health等的新值,因为player1指向内存中的Fighter对象,该对象与fighter1在函数对其进行干扰时所指向的对象相同。

相关问题