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

Swift中如何将函数作为变量传递且初始化时不执行?

Swift 结构体技能函数绑定问题

我希望通过Skill结构体定义技能,技能需包含可灵活配置的函数(示例为skillActionsToArmor())。现有代码如下:

struct Player {
    var armor:      Int
    var actions:    Int
    var skills:     [Skill]?
    
    init(actions: Int, armor: Int) {
        self.actions = actions
        self.armor   = armor
        self.skills  = [Skill(ID: 0, name: "Armor", function: skillActionsToArmor()  )]
    }
    
   mutating func skillActionsToArmor() {
        self.armor += self.actions
        self.actions = 0
    }
}

struct Skill {
    var ID       : Int
    var name     : String
    var function : ()
}

初始化Player时,函数会直接执行,这不符合需求——我希望后续将技能绑定到按钮,仅在按钮点击时执行。

我尝试将Skill的function定义为:

var function: () -> Void

并通过以下方式传递函数(不带()):

self.skills = [Skill(ID: 0, name: "Armor", function: skillActionsToArmor  )]

但此时出现错误:

Escaping autoclosure captures 'inout' parameter 'self'

请问如何修改函数变量或初始化方法,以实现后续从Player结构体中随时执行该函数(例如通过Player.skills[0].function()调用)?


解决方案

方案1:将Player改为类(推荐)

结构体是值类型,mutating方法捕获self会触发逃逸闭包的所有权问题。改为类(引用类型)后,无需mutating关键字,函数可直接绑定self:

class Player {
    var armor: Int
    var actions: Int
    var skills: [Skill]?
    
    init(actions: Int, armor: Int) {
        self.actions = actions
        self.armor = armor
        self.skills = [Skill(ID: 0, name: "Armor", function: skillActionsToArmor)]
    }
    
    func skillActionsToArmor() {
        self.armor += self.actions
        self.actions = 0
    }
}

struct Skill {
    var ID: Int
    var name: String
    var function: () -> Void
}

// 调用示例
var player = Player(actions: 5, armor: 10)
player.skills?[0].function() // 按钮点击时执行此调用

方案2:保持结构体,调整闭包参数

如果必须使用结构体,可将技能函数改为接收inout Player的闭包,调用时手动传入可变的self:

struct Player {
    var armor: Int
    var actions: Int
    var skills: [Skill]?
    
    init(actions: Int, armor: Int) {
        self.actions = actions
        self.armor = armor
        self.skills = [Skill(ID: 0, name: "Armor", function: { (player: inout Player) in
            player.armor += player.actions
            player.actions = 0
        })]
    }
}

struct Skill {
    var ID: Int
    var name: String
    var function: (inout Player) -> Void
}

// 调用示例
var player = Player(actions: 5, armor: 10)
player.skills?[0].function(&player) // 传入可变的player实例执行技能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:07:37