You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4:如何让函数修改外部变量

问题原因&解决方案

嘿,这个问题我太熟悉啦!你碰到的是Swift里值类型和引用类型的核心区别问题~

为什么外部的enemyTwoHP没变化?

因为你定义的Enemy和Player都是结构体(struct),而结构体是Swift里的值类型。当你把enemyTwo传入attackTarget函数的target参数时,Swift会自动创建一个target的完整副本——你在函数里修改的attackTAR其实是这个副本的另一个副本,完全碰不到外面的原始enemyTwo实例,所以函数内打印的是副本的HP,外部打印的还是原始实例的初始值。

两种快速解决方法

方法1:用inout关键字让参数支持修改原始值

把函数的target参数标记为inout,这样Swift就会直接操作原始实例,而不是创建副本。修改后的代码如下:

struct Player { var maxHP: Int var currentHP: Int var maxMP: Int var currentMP: Int var currentLVL: Int var damageATT: Int }
struct Enemy { var maxHP: Int var currentHP: Int var damageAtt: Int }
var alexRider = Player(maxHP: 100, currentHP: 100, maxMP: 100, currentMP: 100, currentLVL: 1, damageATT: 5)
var enemyTwo = Enemy(maxHP: 40, currentHP: 40, damageAtt: 4)

// 修改函数参数为inout
func attackTarget(attacker player: Player, enemy target: inout Enemy) {
    target.currentHP -= player.damageATT
    print("Dealt \(player.damageATT) damage!")
    print("Enemy now has \(target.currentHP) health remaining")
}

// 调用时要在参数前加&符号
attackTarget(attacker: alexRider, enemy: &enemyTwo)
print(enemyTwo.currentHP) // 现在会输出35啦!

方法2:把Enemy改成类(class)

类是Swift里的引用类型,传递参数时传递的是实例的引用,函数里修改的就是原始实例的属性。修改后的代码如下:

struct Player { var maxHP: Int var currentHP: Int var maxMP: Int var currentMP: Int var currentLVL: Int var damageATT: Int }
// 把Enemy从struct改成class,需要手动添加初始化器
class Enemy { 
    var maxHP: Int 
    var currentHP: Int 
    var damageAtt: Int 
    
    init(maxHP: Int, currentHP: Int, damageAtt: Int) {
        self.maxHP = maxHP
        self.currentHP = currentHP
        self.damageAtt = damageAtt
    }
}
var alexRider = Player(maxHP: 100, currentHP: 100, maxMP: 100, currentMP: 100, currentLVL: 1, damageATT: 5)
var enemyTwo = Enemy(maxHP: 40, currentHP: 40, damageAtt: 4)

// 函数不需要修改,直接使用即可
func attackTarget(attacker player: Player, enemy target: Enemy) {
    target.currentHP -= player.damageATT
    print("Dealt \(player.damageATT) damage!")
    print("Enemy now has \(target.currentHP) health remaining")
}

attackTarget(attacker: alexRider, enemy: enemyTwo)
print(enemyTwo.currentHP) // 同样会输出35!

怎么选?

  • 如果你的敌人需要独立的副本(比如生成多个完全一样但状态独立的敌人),优先用struct + inout的组合,符合值类型的设计初衷。
  • 如果敌人是需要共享状态的实例(比如全局唯一的Boss),用class更合适,引用类型的特性会让状态修改更直接。

内容的提问来源于stack exchange,提问作者QuantamPulse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:02:39