这是我的枚举:
enum E {
case a(Int), b(String)
}
枚举的关联值类型是唯一的,并且始终是唯一的。
比方说我有这个变量:
let myInt = 0
我想基于变量E
,动态地创建一个myInt
的实例。这应该导致:
E.a(0)
但是在“现实世界”中,我不知道我得到了什么财产。我只知道一件事:我可以用它初始化枚举E
。我需要根据属性值动态初始化枚举。我目前在属性上有一个巨大的开关来初始化枚举,我不希望那样。
但是我不知道如何完成这项任务。我尝试镜像枚举类型,但是我得到了一个复杂的类型,即使知道类型,我也不知道如何继续进行初始化。
所以我得到了某种类型的属性。我知道某些类型与枚举E中的情况匹配,因为恰好有一种情况下关联值对应于属性类型。我想用属性的值在这种情况下初始化该枚举的实例。
答案 0 :(得分:1)
您可以使用自定义的初始值设定项:(我使用了更具描述性的名称)
enum TypeFinder {
case int(Int)
case string(String)
case unknown(Any)
init(value: Any) {
switch value {
case let v as Int: self = .int(v)
case let v as String: self = .string(v)
default: self = .unknown(value)
}
}
}
测试:
var unknownTypeValue: Any = "Testing.."
print(TypeFinder(value: unknownTypeValue))
unknownTypeValue = 1234
print(TypeFinder(value: unknownTypeValue))
unknownTypeValue = true
print(TypeFinder(value: unknownTypeValue))
答案 1 :(得分:1)
如果您唯一的起点是最终将成为关联值的类型,则可以使用switch
语句:
enum E {
case a(Int)
case b(String)
init(associatedValue: Any) {
switch associatedValue {
case is Int:
self = .a(associatedValue as! Int)
case is String:
self = .b(associatedValue as! String)
default:
fatalError("Unrecognized type!")
}
}
}
let response = E(associatedValue: 1) // .a(1)
let other = E(associatedValue: "haha!") // .b("haha!")
这里的问题是此开关必须是详尽无遗的,这意味着必须覆盖所有所有类型。因此,您要么需要一个垃圾堆(.unreachable(Any)
),要么需要一个fatalError
,以便可以在开发中抓住它们。
答案 2 :(得分:0)
我相信你可以做这样的事情
enum E: ExpressibleByStringLiteral, ExpressibleByIntegerLiteral {
case a(Int), b(String)
init(stringLiteral value: StringLiteralType) {
self = .b(value)
}
init(integerLiteral value: IntegerLiteralType) {
self = .a(value)
}
}