Jer*_*kar 1 generics enums swift
我有一个数组,是从服务器发送的 JSON 中解码的。我想在一行代码中检索节点的值并将其转换为枚举值。可能会发生几个错误:(1)节点不存在,(2)节点值不是字符串(我的枚举只有字符串原始值),或者(3)提供的字符串不适合枚举中的任何现有值。
目前,我对 Dictionary 进行了扩展,使我能够将 (1) 和 (2) 放在一行中用于枚举以外的其他内容,并且如果发生错误,则可以轻松传播错误:
struct MemberOptions : MyDecodable
{
var name:String
var age:Int
var facebookAccount:FacebookAccount
init(from array:[String:Any]) throws
{
// throw exception if node name doesn't exist, is json<null> or if it's value is not castable to the providen parameter (raw types or more complex object implementing MyDecodable protocol)
name = try array.getSafe("name", String.self)
age = try array.getSafe("age", Int.self)
facebookAccount = try array.getSafe("fb", FacebookAccount.self)
}
}
Run Code Online (Sandbox Code Playgroud)
现在是棘手的部分:我想要 (3) 来表示枚举,也就是说,对于给定的枚举,如果提供的字符串原始值不是已知的枚举值,则在一行中传播错误。我看到如果原始字符串值不存在,枚举的默认 init 返回 nil 。我希望它抛出异常。
当然,我可以为所有枚举创建一个会引发异常的 init,但这不是通用的,这将是多余的代码。当然,我也可以在我的商务课程中这样做:
if let enumVal = MyEnum(rawValue: try array.getSafe("enumKey", String.self))
{
self.enumVal = enumVal
}
else
{
throw ValueNotPresentException()
}
Run Code Online (Sandbox Code Playgroud)
但它仍然不够通用,我必须为我想要检索的每个枚举编写这 4 行。
我想要的是所有枚举上的一些共享函数,getSafely(raw: myRawString) throws如果原始值不存在,类似的函数会抛出异常,而不是返回 nil。然后我可以将 (1) (2) 和 (3) 写在一行中,而不必编写冗余代码:
enumProp = try EnumType.getSafely(fromRaw: try array.getSafely("key", String.self))
Run Code Online (Sandbox Code Playgroud)
有没有办法在 Swift 中制作这样一个通用系统(可能使用枚举协议或一些反射)?你会怎么处理?
您可以扩展RawRepresentable并创建一个抛出异常Error而不是返回的初始值设定项nil:
enum Exception: Error {
case valueNotPresent
}
Run Code Online (Sandbox Code Playgroud)
extension RawRepresentable {
init(_ rawValue: RawValue) throws {
guard let value = Self(rawValue: rawValue) else {
throw Exception.valueNotPresent
}
self = value
}
}
Run Code Online (Sandbox Code Playgroud)
游乐场测试:
enum FacebookAccount: String {
case a, b, c
}
do {
let fbAccount = try FacebookAccount("d")
print(fbAccount)
} catch {
print(error) // "valueNotPresent\n"
}
Run Code Online (Sandbox Code Playgroud)