gpt4 book ai didi

swift - 如何在 Swift 4.2 中获取枚举的下一个案例(即编写循环方法)

转载 作者:搜寻专家 更新时间:2023-10-30 22:30:17 26 4
gpt4 key购买 nike

Swift 4.2 引入了一个新的 CaseIterable 协议(protocol),它自动生成枚举中所有案例的数组属性。
现在我想为从 CaseIterable 继承的 Enum 实现一个默认方法,它可以返回给定案例的下一个案例。如果这个case是最后一个case,返回第一个case。像一个圆圈。
如果我为特定枚举编写此代码,它会正常工作:

enum Direction: CaseIterable {
case east, south, west, north

func next() -> Direction {
let all = type(of: self).allCases // 1
if self == all.last! {
return all.first!
} else {
let index = all.firstIndex(of: self)!
return all[index + 1]
}
}
}

print(Direction.east.next()) // south
print(Direction.north.next()) // east

但是我想对很多Enum实现这个功能。重复复制和粘贴代码是不好的(更不用说这段代码对于每个 Enum 都是完全相同的)。
所以我试过了。但是出了点问题。
(我建议您将以下代码复制到 Playground 上,您可以更快地理解这个问题):

extension CaseIterable {
func next() -> Self {
let all = type(of: self).allCases // 1
if self == all.last { // 2
return all.first!
} else {
let index = all.firstIndex { (ele) -> Bool in
self == ele // 3
}
return all[index + 1]
}
}
}

三点:

  1. all的类型是Self.AllCases,这是一个Collection类型。但是在上面的方法中,它是[Direction]
  2. 第 2 行有一个错误说 类型“Self.AllCases”的值没有成员“last”(即使我避免使用last,也无法避免第3行的错误。)
  3. 在第 3 行,错误是二元运算符“==”不能应用于两个“Self”操作数

即使我使用通用约束,它也是一样的。

func next<T: CaseIterable>(element: T) -> T {...}

有什么解决办法吗? :)

最佳答案

您的方法存在一些问题:

  • Collection 协议(protocol)没有定义last 属性。
  • 为了将元素与 == 进行比较,它们必须是 Equatable
  • 集合索引不一定是整数,它们必须递增使用 index(after:)

这似乎是一个可行的解决方案(使用 Xcode 10.0 beta 2 测试):

extension CaseIterable where Self: Equatable {
func next() -> Self {
let all = Self.allCases
let idx = all.firstIndex(of: self)!
let next = all.index(after: idx)
return all[next == all.endIndex ? all.startIndex : next]
}
}

示例:

enum Direction: CaseIterable {
case east, south, west, north
}

print(Direction.east.next()) // south
print(Direction.north.next()) // east

备注:

  • 只有没有关联值的枚举是CaseIterable,并且这些也是 Equatable (但编译器没有弄清楚通过它自己)。因此 Self: Equatable 不是真正的限制。
  • Self.allCases 可以在 Swift 4.2 中使用来访问类型属性来自实例方法。
  • 强制解包是安全的,因为我们知道值是allCases 的一个元素。
  • 你的 enum Direction: CaseIterable 编译因为具体enum Direction 类型是 Equatable,它的 Direction.allCases 是一个 Array – 它有整数索引和一个 last 属性。

关于swift - 如何在 Swift 4.2 中获取枚举的下一个案例(即编写循环方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51103795/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com