感谢@New Dev和@Joakim Danielson的帮助,我用@Joakim Danielson的回答改进了我的代码。
我有一个扩展方法,可以根据给定的字符串枚举为视图分配可访问性标识符。我更新了方法,直接接受字符串枚举案例作为参数,从而完全消除了对AccessibilityId枚举类的需求,如下所示,太棒了!
之前:
.accessibility(identifier: .home(.clickButton))
// Simplified for StackOverflow.
// Imagine 20 more cases..
enum AccessibilityId {
case home(HomeId)
var rawValue: String {
switch self {
case .home(let id):
return id.rawValue
}
}
}
extension View {
func accessibility(identifier: AccessibilityId) -> ModifiedContent<Self, AccessibilityAttachmentModifier> {
self.accessibility(identifier: identifier.rawValue)
}
}
之后:
.accessibility(identifier: HomeId.clickButton)
extension View {
func accessibility<T: RawRepresentable>(identifier: T) -> ModifiedContent<Self, AccessibilityAttachmentModifier> where T.RawValue == String {
self.accessibility(identifier: identifier.rawValue)
}
}
---------------------------------------------------------------
enum Item {
case animal(AnimalId)
case vehicle(VehicleId)
case food(FoodId)
var rawValue: String {
switch self {
case .animal(let id):
return id.rawValue
case .vehicle(let id):
return id.rawValue
case .food(let id):
return id.rawValue
}
}
}
enum AnimalId: String {
case cat
case dog
}
// etc.
// Imagine more cases and more enums.
enum Item {
case animal(AnimalId)
case vehicle(VehicleId)
case food(FoodId)
var rawValue: String {
switch self {
case self as StringEnum:
return id.rawValue
default:
return ""
}
}
}
func test() {
foo(.animal(.cat))
foo(.vehicle(.plane))
foo(.food(.tacos))
}
func foo(_ item: Item) {
print(item.rawValue)
}
我对这种用法很满意,但我想减少给定switch语句中重复案例的数量。注意它们都是如何返回id. rawValue的。上面只是一个例子,实际上我有大约30个案例。
有没有办法让我在一个开关中捕获所有嵌套字符串枚举,或者让案例减少我必须编写的重复代码而不会失去预期的用法?
谢谢你的努力,我希望能为我的代码找到改进!
这是一个解决方案,它不是基于Item是枚举,而是基于泛型结构
struct Item<T: RawRepresentable> where T.RawValue == String {
let thing: T
var rawValue: String {
thing.rawValue
}
}
使用此解决方案,您无需更改其他枚举。示例
let item1 = Item(thing: AnimalId.cat)
let item2 = Item(thing: VehicleId.car)
print(item1.rawValue, item2.rawValue)
产出
猫车
您需要所有这些关联值之间的共同点,例如与共享协议的一致性,例如协议RawStringValue
:
protocol RawStringValue {
var rawValue: String { get }
}
// String enums already conform without any extra implementation
extension AnimalId: RawStringValue {}
extension VehicleId: RawStringValue {}
extension FoodId: RawStringValue {}
然后你可以在里面创建一个switch self
,如下所示:
var rawValue: String {
switch self {
case .animal (let id as RawStringValue),
.vehicle (let id as RawStringValue),
.food (let id as RawStringValue):
return id.rawValue
}
}
话虽如此,带有关联值的枚举不是最方便使用的类型,因此请确保它是正确的选择。