gpt4 book ai didi

swift - 扩展协议(protocol)属性以在 Swift 中提供默认实现

转载 作者:搜寻专家 更新时间:2023-10-31 08:21:48 24 4
gpt4 key购买 nike

我有一个用于多个枚举的协议(protocol),其中包括 Swift 4.2 的 CaseIterable

    public protocol CycleValue: CaseIterable {

/// Computed property that returns the next value of the property.
var nextValue:Self { get }
}

CycleValue 的一个用例是使用 Theme 属性:

@objc public enum AppThemeAttributes: CycleValue  {

case classic, darkMode // etc.

public var nextValue: AppThemeAttributes {
guard self != AppThemeAttributes.allCases.last else {
return AppThemeAttributes.allCases.first!
}

return AppThemeAttributes(rawValue: self.rawValue + 1)!
}
}

我还有其他用例;例如,按钮类型。 CaseIterable 使 nextValue 的实现变得容易,但对所有类型的 CycleValue 都是一样的。

我想实现 CycleValue 的扩展,为 nextValue 属性提供默认实现并避免重复代码(即:DRY!)。

我一直在与 PAT(协议(protocol)关联类型)作斗争。似乎无法获得正确的语法。

应该可以吧?我如何为 nextValue 提供默认实现以避免 ode 重复?

最佳答案

一个可能的解决方案是在 allCases 集合中定位当前值,并返回下一个元素(或环绕到第一个元素):

public protocol CycleValue: CaseIterable, Equatable {
var nextValue: Self { get }
}

public extension CycleValue {
var nextValue: Self {
var idx = Self.allCases.index(of: self)!
Self.allCases.formIndex(after: &idx)
return idx == Self.allCases.endIndex ? Self.allCases.first! : Self.allCases[idx]
}
}

(请注意,两种强制解包都是安全的!)示例:

public enum AppThemeAttributes: CycleValue  {
case classic, darkMode // etc.
}

let a = AppThemeAttributes.classic
print(a) // classic
let b = a.nextValue
print(b) // darkMode
let c = b.nextValue
print(c) // classic

协议(protocol)必须符合 Equatable 才能编译,但是不是真正的限制:CaseIterable 协议(protocol)不能有关联值,以便编译器始终可以综合Equatable 一致性。

关于swift - 扩展协议(protocol)属性以在 Swift 中提供默认实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52459906/

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