如何简化冗长的Swift switch语句?六个同类代码块需精简
精简属性修正值的Swift代码
你这段代码是典型的D&D类游戏属性值转修正值的逻辑,功能没问题但冗余度极高,完全可以用数学公式+边界判断替代冗长的switch,还能轻松复用在六个属性上:
原始臃肿代码
let strStatResult = strStat strengthModLabel.text = String(strStatResult) switch strStatResult { case let strStatResult where strStatResult == 1: strengthModLabel.text = "-5" case let strStatResult where strStatResult == 2 || strStatResult == 3: strengthModLabel.text = "-4" case let strStatResult where strStatResult == 4 || strStatResult == 5: strengthModLabel.text = "-3" case let strStatResult where strStatResult == 6 || strStatResult == 7: strengthModLabel.text = "-2" case let strStatResult where strStatResult == 8 || strStatResult == 9: strengthModLabel.text = "-1" case let strStatResult where strStatResult == 10 || strStatResult == 11: strengthModLabel.text = "0" case let strStatResult where strStatResult == 12 || strStatResult == 13: strengthModLabel.text = "+1" case let strStatResult where strStatResult == 14 || strStatResult == 15: strengthModLabel.text = "+2" case let strStatResult where strStatResult == 16 || strStatResult == 17: strengthModLabel.text = "+3" case let strStatResult where strStatResult == 18 || strStatResult == 19: strengthModLabel.text = "+4" case let strStatResult where strStatResult == 20 || strStatResult == 21: strengthModLabel.text = "+5" case let strStatResult where strStatResult == 22 || strStatResult == 23: strengthModLabel.text = "+6" case let strStatResult where strStatResult == 24 || strStatResult == 25: strengthModLabel.text = "+7" case let strStatResult where strStatResult == 26 || strStatResult == 27: strengthModLabel.text = "+8" case let strStatResult where strStatResult == 28 || strStatResult == 29: strengthModLabel.text = "+9" case let strStatResult where strStatResult == 30: strengthModLabel.text = "+10" default: strengthModLabel.text = "Error" }
精简方案
先梳理规律:属性值和修正值的对应关系完全符合D&D官方公式:修正值 = floor((属性值 - 10) / 2),利用这个公式可以彻底干掉所有case判断,还能封装成通用函数处理六个属性:
通用函数实现
func updateAbilityModLabel(_ label: UILabel, for abilityScore: Int) { // 判断属性值是否在合法范围(1-30) guard (1...30).contains(abilityScore) else { label.text = "Error" return } // 计算修正值 let mod = Int(floor(Double(abilityScore - 10) / 2)) // 格式化显示文本:0直接显示0,正数加+,负数正常显示 label.text = mod == 0 ? "0" : mod > 0 ? "+\(mod)" : "\(mod)" }
调用方式
六个属性只需要调用六次函数即可,再也不用写重复的switch:
// 力量修正 updateAbilityModLabel(strengthModLabel, for: strStat) // 敏捷修正 updateAbilityModLabel(dexterityModLabel, for: dexStat) // 体质修正 updateAbilityModLabel(constitutionModLabel, for: conStat) // 智力修正 updateAbilityModLabel(intelligenceModLabel, for: intStat) // 感知修正 updateAbilityModLabel(wisdomModLabel, for: wisStat) // 魅力修正 updateAbilityModLabel(charismaModLabel, for: chaStat)
为什么不用循环?
循环在这里完全没必要——因为对应关系是明确的数学公式,直接计算比遍历判断效率高得多,而且代码更简洁易维护。如果后续属性范围调整,只需要修改公式或合法范围即可,不用改动一堆case。
内容的提问来源于stack exchange,提问作者Lucas Rider
相关产品推荐
相关产品推荐

