我想做的是创建一个协议(protocol)扩展来从枚举中获取一组原始值。例如说我有以下内容:
enum TestType: String, EnumIteratable {
case unitTest = "Unit Test"
case uiTest = "UI Test"
}
class EnumIterator: NSObject {
class func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T> {
var i = 0
return anyGenerator {
let next = withUnsafePointer(&i) { UnsafePointer<T>($0).memory }
return next.hashValue == i++ ? next : nil
}
}
class func getValues<T: Hashable>(_: T.Type) -> [T] {
let iterator = self.iterateEnum(T)
var returnArray = [T]()
for val in iterator {
returnArray.append(val)
}
return returnArray
}
}
如何实现 EnumIteratable 协议(protocol),以便调用 TestType.getRawValues() 并让它返回所有原始枚举值的字符串数组?
谢谢!
最佳答案
Scott 的解决方案可能就是您想要的。但是,如果您正在寻找可以应用于任意 future 枚举并允许其他情况的更通用的东西,您可以试试这个:
首先,您需要一种方法来迭代枚举案例。我从这里使用了这个实现:https://stackoverflow.com/a/28341290/914887
func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T> {
var i = 0
return anyGenerator {
let next = withUnsafePointer(&i) { UnsafePointer<T>($0).memory }
return next.hashValue == i++ ? next : nil
}
}
然后,您可以创建您的协议(protocol),它定义了您想要的静态函数:
protocol EnumIteratable {
typealias ENUM_TYPE:Hashable, RawRepresentable = Self
static func getAllValues() -> [ ENUM_TYPE ]
static func getRawValues() -> [ ENUM_TYPE.RawValue ]
}
我使用关联类型来允许符合规范的枚举将它们的类型指定给协议(protocol)。 getAllValues
不是绝对必要的,但它简化了逻辑。
然后,您可以定义您的通用默认实现:
extension EnumIteratable {
static func getAllValues() -> [ ENUM_TYPE ]
{
var retval = [ ENUM_TYPE ]()
for item in iterateEnum( ENUM_TYPE )
{
retval.append( item )
}
return retval
}
static func getRawValues() -> [ ENUM_TYPE.RawValue ]
{
return getAllValues().map( { ( item:ENUM_TYPE ) -> ENUM_TYPE.RawValue in item.rawValue } )
}
}
最后,您需要做的就是在需要迭代枚举时随时遵守该协议(protocol):
enum TestType: String, EnumIteratable {
case unitTest = "Unit Test"
case uiTest = "UI Test"
}
TestType.getRawValues()
这里的优点是,我可以为 integrationTest
添加一个新案例,我只需要在一个地方添加它。
关于swift - 如何编写协议(protocol)扩展以从 Swift 枚举中获取所有 rawValues,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33589055/