如何为多个Swift枚举编写复用DRY函数?代码优化问询
解决方案:协议+协议扩展实现复用
当然可以!其实用协议+协议扩展就能完美解决这个问题,既符合Swift的设计模式,又能彻底避免重复代码,完全遵循DRY原则。
具体步骤:
定义一个带约束的协议
我们先创建一个协议,它继承自CaseIterable(这样能直接使用allCases),同时要求每个枚举 case 必须实现title计算属性:protocol CaseIterableWithTitle: CaseIterable { var title: String { get } }给协议添加默认实现
接下来给这个协议扩展,统一实现titles静态属性的逻辑——这部分就是你之前重复写的循环,现在只需要写一次:extension CaseIterableWithTitle { static var titles: [String] { // 用map替代手动循环,代码更简洁 allCases.map { $0.title } } }修改现有枚举,遵循协议
现在只需要让你的枚举遵循CaseIterableWithTitle协议,同时保留各自的title实现(毕竟每个枚举的标题逻辑是独有的),去掉重复的titles属性即可:enum CustomerTypes: Int, CaseIterableWithTitle { case NewCustomer = 0 case ExistingCustomer case Myself var title: String { switch self { case .NewCustomer: return StandardStrings.NewDrive.NewCustomer.string case .ExistingCustomer: return StandardStrings.NewDrive.ExistingCustomer.string case .Myself: return StandardStrings.NewDrive.Myself.string } } } enum EnquiryTypes: Int, CaseIterableWithTitle { case Phone = 0 case FaceToFace var title: String { switch self { case .Phone: return StandardStrings.Misc.Phone.string case .FaceToFace: return StandardStrings.Misc.FaceToFace.string } } }
为什么这个方案可行?
- 精准控制范围:只有明确遵循
CaseIterableWithTitle的枚举才会获得titles属性,不会影响其他无关的Int枚举,解决了你之前担心的“不想给所有带Int原始值的枚举加功能”的问题。 - 彻底消除重复:
titles的核心逻辑只写一次,所有遵循协议的枚举自动复用,完全符合DRY原则。 - 利用Swift特性:通过协议继承
CaseIterable,直接使用allCases,不需要手动实现类似_allCases的额外属性,规避了你之前尝试协议时遇到的问题。
现在你可以直接调用CustomerTypes.titles或者EnquiryTypes.titles,效果和之前完全一样,但代码简洁了很多!
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

