我喜欢Swift允许使用枚举方法.我正在尝试使用方法,但我正在寻找一种更可扩展的方法:
enum CopyState{
case binary, hex, both
init(){
self = .both
}
mutating func next() {
if self == .binary{
self = .hex
} else if self == .hex {
self = .both
} else if self == .both{
self = .binary
}
}
}
var state = CopyState()
state.next()
Run Code Online (Sandbox Code Playgroud)
我想基本上将枚举转换为整数,并以总模数选项的模数递增
添加或删除枚举选项很麻烦(我使用的是last()和next()方法).
Cri*_*tik 14
更新从Swift 4.2开始,您可以使用新添加的支持CaseIterable协议,该协议增加了编译器支持,以生成枚举的所有案例列表.然后你的枚举可能看起来像这样(不再是硬编码的起始值):
enum CopyState: CaseIterable {
case binary, hex, both
mutating func next() {
let allCases = type(of: self).allCases
self = allCases[(allCases.index(of: self)! + 1) % allCases.count]
}
}
Run Code Online (Sandbox Code Playgroud)
或者,更加冗长,但更好地分离了关注点:
extension CaseIterable where Self: Equatable {
mutating func next() {
let allCases = Self.allCases
// just a sanity check, as the possibility of a enum case to not be
// present in `allCases` is quite low
guard let selfIndex = allCases.index(of: self) else { return }
let nextIndex = Self.allCases.index(after: selfIndex)
self = allCases[nextIndex == allCases.endIndex ? allCases.startIndex : nextIndex]
}
}
enum CopyState: CaseIterable {
case binary, hex, both
}
var state = CopyState.hex
state.next()
print(state) // both
state.next()
print(state) // binary
Run Code Online (Sandbox Code Playgroud)
您可以使用CaseIterable枚举的原始值(请注意,如果您不指定它,这也是默认的原始值),并使用它如下所示:
extension Collection {
// adding support for computing indexes in a circular fashion
func circularIndex(after i: Index) -> Index {
let nextIndex = index(after: i)
return nextIndex == endIndex ? startIndex : nextIndex
}
}
extension Collection where Element: Equatable {
// adding support for retrieving the next element in a circular fashion
func circularElement(after element: Element) -> Element? {
return index(of: element).map { self[circularIndex(after: $0)] }
}
}
// Protocol to allow iterating in place (similar to a type conforming to both Sequence and IteratorProtocol)
protocol InPlaceIterable {
mutating func next()
}
extension InPlaceIterable where Self: CaseIterable, Self: Equatable {
// adding default implementation for enums
mutating func next() {
self = type(of: self).allCases.circularElement(after: self)!
}
}
// now the enums need only the protocol conformances, they get the
// functionalities for free
enum CopyState: CaseIterable, InPlaceIterable {
case binary, hex, both
}
Run Code Online (Sandbox Code Playgroud)
只要您按连续顺序获得枚举案例的原始值,这样就可以正常工作.默认情况下,编译器会分配连续的原始值.
Int如果第一种情况发生变化,您还需要记住更新方法,否则它将无法正常工作.
@MartinR建议的上述限制的替代方法是强制解包原始值零:
enum CopyState: Int {
case binary, hex, both
mutating func next(){
self = CopyState(rawValue: rawValue + 1) ?? .binary
}
}
var state = CopyState.hex
state.next()
print(state) // both
state.next()
print(state) // binary
Run Code Online (Sandbox Code Playgroud)
当第一个枚举案例发生更改时,上述代码不需要更新方法,但如果枚举的起始原始值发生更改,则可能会导致应用程序崩溃.
| 归档时间: |
|
| 查看次数: |
1739 次 |
| 最近记录: |