以下代码(无错误编译)检索元素的索引 在特定的CaseIterable枚举类型中
public enum MyEnum : CaseIterable {
case ONE, TWO, THREE
public func ordinal() -> Int? {
return MyEnum.allCases.firstIndex(of: self)
}
}
我想创建一个通用函数以与所有CaseIterable枚举一起使用。
如果我尝试:
public extension CaseIterable {
public func ordinal() -> Int? {
return CaseIterable.allCases.firstIndex(of: self)
}
}
我收到一个编译器错误“ Member 'allCases' cannot be used on value of protocol type 'CaseIterable'; use a generic constraint instead
”,这很合逻辑,因为实际的枚举类型未知。”
当我尝试CaseIterable<T>
时,由于没有将CaseIterable声明为泛型类型,我又遇到了另一个错误。
有办法吗?
答案 0 :(得分:2)
需要进行更改:
Self.AllCases.Index?
,而不是Int?
。实际上,这些类型将是等效的,如下所示。Equatable
,因为使用firstIndex(of:)
时必须等同。再次,在实践中,任何CaseIterable
通常都是没有关联值的枚举,这意味着它会自动等价。nil
,因为您在CaseIterable
中发现了一种情况。因此,您可以删除返回类型(Self.AllCases.Index
)上的可选内容,并强制展开。示例:
public extension CaseIterable where Self: Equatable {
public func ordinal() -> Self.AllCases.Index {
return Self.allCases.firstIndex(of: self)!
}
}
enum Example: CaseIterable {
case x
case y
}
Example.y.ordinal() // 1
type(of: Example.y.ordinal()) // Int
就我个人而言,我想补充一点,“序数”通常意味着与您正在做的事情不同,并且我建议将函数名称更改为elementIndex()
或其他名称。但这是一个问题。