通过 Enum 快速递增

2024-03-03

我喜欢 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()

我想本质上将枚举转换为整数,并以枚举选项总数为模递增它

添加或删除枚举选项很麻烦(我正在使用last()和next()方法)。


Update从 Swift 4.2 开始,您可以利用新添加的支持CaseIterable协议,它添加了编译器支持以生成枚举的所有情况的列表。虽然@ninestonescomment https://stackoverflow.com/questions/48612076/swift-increment-through-enum/48612152#comment108080020_48612152指出我们不能保证allCases要以与定义相同的顺序返回案例,合成的实现会执行此操作,并且定义不太可能更改。

然后,您的枚举可能看起来像这样(不再有硬编码的起始值):

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]
    }
}

您可以让所有人都可以使用此功能CaseIterable enums:

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

或者,更详细一点,但更好地分离关注点:

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
}

你可以使用Int作为枚举的原始值(请注意,如果您不指定它,这也是默认的原始值),并像这样使用它:

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

只要您拥有连续顺序的枚举案例的原始值,这种方法就可以正常工作。默认情况下,编译器分配连续的原始值。

您还需要记住更新next()方法如果第一种情况发生变化,否则它将不再正确工作。

@MartinR 建议的上述限制的替代方法是强制解开原始值零:

mutating func next(){
    self = CopyState(rawValue: rawValue + 1) ?? CopyState(rawValue: 0)!
}

当第一个枚举情况发生更改时,上面的代码不需要更新方法,但是如果枚举的起始原始值发生更改,则可能会导致应用程序崩溃。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 Enum 快速递增 的相关文章

  • 进入后台时 Alamofire 请求卡住?

    我正在使用 Alamofire 调用 Web 服务 该服务需要相当长的时间才能加载 如果应用程序进入后台 当我返回应用程序时 我会被加载程序卡住 我想这是因为调用永远不会向我的完成处理程序返回任何内容 我该如何解决这个问题 您可以使用后台抓
  • 如何在 Swift 中使用 CoreBluetooth 更新 BLE 设备的电池电量?

    func peripheral peripheral CBPeripheral didDiscoverCharacteristicsFor service CBService error Error for c in service cha
  • 带约束的嵌套集合视图的意外行为 (Swift 4)

    我的表格视图中有一个单元格 其中包含水平分页集合视图 该集合视图的每个页面内都有一个垂直集合视图 为了避免 滚动滚动 问题 我在垂直集合视图中禁用了垂直滚动 垂直集合视图的单元格计数不是静态的 可以是任意数字 因此 这会产生一个问题 集合视
  • NSURLCache 不缓存

    我正在使用 Xcode 6 1 6A1030 iOS7 和 iOS8 模拟器 NSURLCache 似乎没有缓存任何东西 我使用 Cache Control 标头 我的服务器返回带有 max age 6000 的 Cache Control
  • 如何将CIFilter应用到UIView上?

    根据Apple docs 过滤属性CALayer不支持iOS 当我使用正在申请的应用程序之一时CIFilter to UIView即 Splice Funimate 和 Artisto 的视频编辑器 Videoshow FX 这意味着我们可
  • 在 Swift 中以编程方式为 iOS 制作带有名字首字母的图像,例如 Gmail

    我需要在 UITableView 中显示与其姓名相对应的每个用户的个人资料图片 在下载图像之前 我需要显示一张带有他名字的第一个字母的图像 就像在 GMail 应用程序中一样 如何在 Swift for iOS 中以编程方式执行此操作 不需
  • 在 UITableView 的部分标题文本下方添加一些边距

    我已经设计了标题文本的样式 func tableView tableView UITableView cellForRowAtIndexPath indexPath NSIndexPath gt UITableViewCell let ce
  • 为什么在 C++ 中声明枚举时使用 typedef?

    我已经很多年没有写过任何 C 了 现在我正试图重新开始 然后我遇到了这个并考虑放弃 typedef enum TokenType blah1 0x00000000 blah2 0X01000000 blah3 0X02000000 Toke
  • 如何检测 swiftui 中是否存在键盘

    我想知道按下按钮时键盘是否存在 我该怎么做 我已经尝试过 但我没有任何运气 谢谢 使用该协议 KeyboardReadable 你可以符合任何View并从中获取键盘更新 KeyboardReadable协议 import Combine i
  • 为 Swift 对象/属性设置观察者

    我一直在寻找一种在连接到 Mac 的显示器数量发生变化时触发方法的方法 我知道我可以获得 NSScreen screens count 的值 但我需要找到一种方法来在该值发生变化时创建通知或其他内容 或者指示所连接的显示器数量发生变化的其他
  • Swift 3 中的 JSON 解析

    有没有人能够找到一种在 Swift 3 中解析 JSON 文件的方法 我已经能够返回数据 但在将数据分解为特定字段时我没有成功 我会发布示例代码 但我已经尝试了很多不同的方法但没有成功 并且没有保存任何代码 我想要解析的基本格式是这样的 提
  • 以编程方式从底部裁剪图像

    我正在开发自定义相机应用程序 一切进展顺利 但我在从底部裁剪图像时遇到了问题 即 裁剪后的图像与原始图像具有完全相同的宽度 但高度将为原始图像的 1 3 并且必须从底部开始 斯威夫特3解决方案 func cropBottomImage im
  • 不明白 Swift 中的闭包示例

    我正在尝试了解 swift 和闭包 我被这个例子困住了 numbers map number Int gt Int in let result 3 number return result 什么是 number Int gt Int 它是一
  • 可以获取位置,但无法获取航向

    我目前只使用模拟器 但我在 iOS 模拟器上快速使用 CoreLocation 时遇到问题 我得到此代码打印的位置更新 但从未得到标题 我不想当然 我正在尝试制作一个指南针类型的应用程序 它将显示目标的方位 class CompassVie
  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • Swift Codable 将空 json 解码为 nil 或空对象

    这是我的代码 class LoginUserResponse Codable var result String var data LoginUserResponseData var mess String public class Log
  • 为什么我不能在 Realm 属性上使用 private

    我正在尝试在 RealmSwift 中存储一个枚举案例 但 Realm 不支持枚举 本文 https medium com it works locally persisting swift enumerations with realm
  • 为什么这个谓词格式会变成 '= nil'

    有人建议这个线程 https stackoverflow com questions 40686005 nspredicate crash after swift 3 migration与我的问题完全相同 但是 我的应用程序没有崩溃 并且我
  • NVActivityIndi​​catorView 仅适用于特定视图

    我正在使用这个库https github com ninjaprox NVActivityIndi catorView https github com ninjaprox NVActivityIndicatorView用于显示加载指示器
  • Swift 中的 UIAlert 自动消失?

    我有以下代码 Creates Alerts on screen for user func notifyUser title String message String gt Void let alert UIAlertController

随机推荐

  • 使用 JavaScript 通过“阅读更多”和“阅读更少”截断文本

    如果我错误地提出了这个问题 或者如果之前有人问过并回答过这个问题 我很抱歉 我的搜索发现了类似的基于 JQuery 的问答 我正在寻找一个纯 JavaScript 解决方案 var len 100 var p document getEle
  • 使用 Fortuna PRNG 在计数器模式下使用 AES 进行随机访问加密:

    我正在构建基于 AES 的文件加密 该加密必须能够在随机访问模式下工作 访问文件的任何部分 例如 可以在 Counter 中使用 AES 但众所周知 我们需要一个不会使用两次的唯一序列 在这种情况下 可以使用简化的 Fortuna PRNG
  • 如何在 Angular 7 的表格上使用 Ngx-pagination

    嗨 我有一个清单 例如 0 姓名 Manu 年龄 21 爱好 Array 4 1 姓名 Anu 年龄 20 爱好 Array 3 2 姓名 nandu 年龄 22 爱好 Array 5 我需要在表格上显示这一点 所以我正在执行下面的代码 t
  • igraph - 邻居作为子图 - make_ego_graph() 作为单个图

    我想构造一个有向网络图的子图 其中所有顶点共享某个顶点属性 例如 V Grph year 1952 及其一阶 直接 邻居 基于仅在出度上 我试过了ego make ego graph neighbors and adjacent verti
  • 如何静默 cvxopt 求解器 [Python]?

    每当我在终端中运行 Python cvsopt 求解器时 它都会打印 pcost dcost gap pres dres 0 8 0742e 00 7 3715e 00 3e 03 5e 01 4e 15 1 6 6241e 01 7 28
  • 如何使用 dplyr 将函数应用于所有非 group_by 列?

    我正在尝试使用 dplyr 包将函数应用于 data frame 中未分组的所有列 我将使用aggregate aggregate Species data iris mean where mean应用于所有未用于分组的列 是的 我知道我可
  • 在 C# 中实现进度条的正确方法

    我正在学习 winforms 我给自己设定了一个简单的目标 即制作一个从空到满的进度条 这是我的畸形尝试 public partial class Form1 Form static BackgroundWorker bw new Back
  • Rails,使用控制器中文件的内容

    我有一个文件在config目录 比方说 my policy txt 我想在控制器中使用该文件的内容 就像使用简单的字符串一样 policy content of config my policy txt 如何实现这个目标 Rails是否提供
  • C 中函数指针语法的用途是什么?

    编辑 有人指出这个问题有点令人困惑 简短的版本是 为什么有一个单独的指针变量 例如 fnPtr 它指向一个函数 例如 fn 当函数名fn本身 没有参数 已经是一个指针 编辑 我正在尝试了解一些内容 并且可以使用社区有关函数指针的反馈 虽然这
  • iText 表格行距从右到左方向(阿拉伯语)

    我的应用程序是用英语和阿拉伯语两个不同版本开发的 我在 iText 中使用 rowspan 和 colspan 创建了 pdf 表 该表在英语版本中完美运行 但在阿拉伯语版本中 rowspan 不起作用 当我使用 setRunDirecti
  • 花式盒子 - 如何从单个缩略图显示幻灯片

    我的缩略图是分页的 因此任何一页上只有 6 个缩略图 大约 4 页 一个类别中总共 24 张图像 如果我将其设置在其中一个页面上 它只会显示该页面上的 6 个相关图像 如何使用 Fancybox 显示所有 24 张图像的幻灯片 提前谢谢了
  • 使用 moment.js 检查日期格式

    我正在从屏幕上的日历中获取这种类型的输入 DD MMM YYYY HH mm a 但用户可以从键盘提供日期 现在我必须检查用户是否以正确的格式提供了日期 我在我的应用程序中大量使用 moment js 并像这样验证它 if angular
  • 计算中位数移动平均单位成本时使用 Over(Partition By)

    早上好 我正在尝试计算特定仓库中每件商品的 12 个月移动平均成本 MAUC 我正在使用 2012 B 分页技巧来计算中位价格 http sqlperformance com 2012 08 t sql queries median htt
  • 在 Xcode 6.0.1 中使用仪器进行分析时应用程序挂起

    我观察到 每当我使用 Xcode 6 0 1 中的工具分析我的应用程序时 每次浏览应用程序时应用程序都会挂起 我正在使用 iPhone 5S iOS 8 0 2 来运行我的应用程序 当我在设备上运行该应用程序时 它运行得很好 找到修复 禁用
  • 使用 php 将事件插入谷歌日历

    如何将活动插入 Google 日历 我正在使用本指南 https developers google com google apps calendar v3 reference events insert https developers
  • 在android上使用ormlite删除?

    我有一个客户端 bean DatabaseField columnName client id generatedId true useGetSet true private Integer clientId DatabaseField c
  • 如何在网页视图中播放本地 swf 文件

    我正在尝试在 webview 中播放本地 swf 文件 保存在 asset 或 sdcard 中 但我没有运气 任何人都可以指导我正确的方法吗 我可以通过 url 播放 swf 文件 但是在 webview 中播放本地文件时遇到困难 swf
  • 如何使用 gson 库将字符串转换为 JsonObject

    请指教如何转换String to JsonObject using gson图书馆 我不成功的做法 String string abcde Gson gson new Gson JsonObject json new JsonObject
  • 如何忽略部分文本并在剩余部分进行搜索和替换? [复制]

    这个问题在这里已经有答案了 在文本文件中进行正则表达式查找和替换时 我想跳过并忽略文本的某些片段 也就是说 应该将文本的某些部分排除在搜索之外 而只对其余部分进行搜索和替换 标准是 1 任何介于START and END应从搜索和替换中排除
  • 通过 Enum 快速递增

    我喜欢 Swift 允许使用枚举方法 我正在尝试使用一种方法 但正在寻找一种更具可扩展性的方法来执行此操作 enum CopyState case binary hex both init self both mutating func n