swift - 为多个枚举创建一个 DRY 函数(枚举子类化?)
问题描述
我有多个枚举,它们都将共享相同的功能。有没有办法编写一次这个函数并让它出现在所有指定的枚举中?这是一个例子:
enum CustomerTypes: Int, CaseIterable {
case NewCustomer = 0
case ExistingCustomer
case Myself
private 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
}
}
static var titles: [String] {
get {
var toReturn: [String] = []
for value in allCases {
toReturn.append(value.title)
}
return toReturn
}
}
}
enum EnquiryTypes: Int, CaseIterable {
case Phone = 0
case FaceToFace
private var title: String {
switch self {
case .Phone : return StandardStrings.Misc.Phone.string
case .FaceToFace : return StandardStrings.Misc.FaceToFace.string
}
}
static var titles: [String] {
get {
var toReturn: [String] = []
for value in allCases {
toReturn.append(value.title)
}
return toReturn
}
}
}
正如您在此处看到的,两个枚举共享相同的“标题”变量。有没有办法我可以创建一个枚举/类,他们可以从中继承这个函数?
以下是我尝试过的一些事情:
你能扩展一个枚举吗?
我考虑过这一点,但我不想扩展所有具有 Int rawValues 的函数
我考虑创建一个协议,然后创建一个采用这样的协议的函数,但我仍然需要在每个枚举上实现 _allCases (因为你不能从 CaseIterable 继承):
protocol RBEnum {
var title: String { get }
var _allCases: [RBEnum] { get }
}
那么有什么想法可以避免在这些枚举上违反 DRY 原则吗?
解决方案
协议是正确的方法。不知道为什么你认为协议不能相互继承,但它们可以,所以你可以让你的协议继承自CaseIterable
.
您还可以titled
通过使用map
而不是for..in
循环并摆脱无用的get
说明符来显着简化。get { ... }
getter 是计算属性的默认访问器,除非您同时创建 getter 和 setter ,否则不需要将闭包包装起来。
protocol Titled: CaseIterable {
var title: String { get }
static var titles: [String] { get }
}
extension Titled {
static var titles: [String] { allCases.map(\.title) }
}
然后,您只需将title
属性保留在您的枚举中,并使它们符合Titled
并且由于您titles
免费获得的默认实现。
与您的问题无关,但枚举案例应该像所有变量一样为 lowerCamelCase。
enum CustomerTypes: Int, Titled {
case newCustomer = 0
case existingCustomer
case myself
var title: String {
switch self {
case .newCustomer : return "new"
case .existingCustomer : return "existing"
case .myself : return "my"
}
}
}
enum EnquiryTypes: Int, Titled {
case phone = 0
case faceToFace
var title: String {
switch self {
case .phone : return "phone"
case .faceToFace : return "face"
}
}
}
推荐阅读
- android - 如何使用 Android.mk 设置 applicationID
- zend-framework - Zend 控制台命令不会响应任何内容
- java - 泛型:无法转换为多个泛型类型
- shell - 如何使用 unix 脚本删除每个会话的旧 Informatica 会话日志文件
- xml - T-SQL XML Modify Syntax 使用变量动态设置标签
- javascript - 如何在转换返回对象的一部分时在 Javascript 中执行数组映射?
- python - Flask 生成独立进程(fork)导致端口在使用中
- hyperledger-fabric - Hyperledger Fabric 多组织设置
- android - 相同的 Android admob 单元仅显示在两个应用程序之一中
- java - 为什么 getJdbcTemplate().query 升级 mySql 后返回空列表?