gpt4 book ai didi

swift - 可以在 Swift 中制作通用类型检查功能吗?

转载 作者:搜寻专家 更新时间:2023-11-01 06:38:44 24 4
gpt4 key购买 nike

我正在为我继承的 Web API 框架添加更好的错误处理。目前它会执行大量强制转换,这会在数据与预期不符时导致崩溃。

我想将 as! 的所有用法替换为检查类型并在失败时抛出异常(带有详细描述)的函数。

这是我到目前为止所得到的:

func checkType<T>(type: AnyClass, value: T?, name: String) throws -> T {
guard let value = value else {
let message = "[\(name)] Expected \(type), but value was nil"
throw PlaidsterError.InvalidType(message)
}

guard value.dynamicType.self == type else {
let message = "[\(name)] Expected \(type), but it was an \(value.dynamicType.self) with value: \(value)"
throw PlaidsterError.InvalidType(message)
}

return value
}

但这有很多问题。它只能接受对象类型,如果类不完全匹配它就会失败(例如 NSString 失败,因为它实际上是一个 __NSCFString),并且它不能与任何类型一起工作,即 String、Int、Double...

我似乎无法为 Any 值类型找到 AnyClass 的同义词,这是第一个问题。此外,似乎不可能执行类似 value.dynamicType.self is type 的操作,因为它表示 type 不是类型。


有没有可能做我想做的事?有没有更好的方法来执行这种类型检查,而无需在解析代码中散布大量样板代码?

我的目标是得到类似这样甚至更简单的东西:

public struct PlaidCategory {

// MARK: Properties
public let id: String
public let hierarchy: [String]
public let type: String

// MARK: Initialization
public init(category: [String: Any]) throws {
id = try checkType(String.self, value: category["id"], name: "id")
hierarchy = try checkType([String].self, value: category["hierarchy"], name: "hierarchy")
type = try checkType(String.self, value: category["type"], name: "type")
}

最佳答案

你可以用另一个泛型类型参数来写这样的东西。

func checkType<T, U>(type: U.Type, value: T?, name: String) throws -> U {
guard let value = value else {
let message = "[\(name)] Expected \(type), but value was nil"
throw PlaidsterError.InvalidType(message)
}

guard let result = value as? U else {
let message = "[\(name)] Expected \(type), but it was an \(value.dynamicType) with value: \(value)"
throw PlaidsterError.InvalidType(message)
}

return result
}

并将其用作:

do {
let n: Any = 3
let t = try checkType(Int.self, value: n, name: "n")
print(t) //->3
} catch let error {
print(error)
}
do {
let n: Any = "x"
let t = try checkType(Int.self, value: n, name: "n")
print(t)
} catch let error {
print(error) //->InvalidType("[n] Expected Int, but it was an _NSContiguousString with value: x")
}

我希望这对您的 PlaidCategory.init(category:) 有用,但未经测试。


再来一个。如果仅在返回类型可推断的情况下使用它,则无需传递 type 参数。

func checkType<T, U>(value: T?, name: String) throws -> U {
guard let value = value else {
let message = "[\(name)] Expected \(U.self), but value was nil"
throw PlaidsterError.InvalidType(message)
}

guard let result = value as? U else {
let message = "[\(name)] Expected \(U.self), but it was an \(value.dynamicType) with value: \(value)"
throw PlaidsterError.InvalidType(message)
}

return result
}

并将其用作:

do {
let n: Any = "x"
let t: Int = try checkType(n, name: "n")
print(t)
} catch let error {
print(error) //->InvalidType("[n] Expected Int, but it was an String with value: x")
}

或:

public struct PlaidCategory {

// MARK: Properties
public let id: String
public let hierarchy: [String]
public let type: String

// MARK: Initialization
public init(category: [String: Any]) throws {
id = try checkType(category["id"], name: "id")
hierarchy = try checkType(category["hierarchy"], name: "hierarchy")
type = try checkType(category["type"], name: "type")
}
}

关于swift - 可以在 Swift 中制作通用类型检查功能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38312970/

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