[英]Swift generics. How to check if the type of Array's Element inherits from other class
我想在我的方法中確定泛型類型是否是數組,如果是,則讀取一些作為數組元素的類型的靜態變量。
我認為這會奏效:
print(T.self)
print(T.self is Array<SPTBaseObject>.Type)
if let A = T.self as? Array<SPTBaseObject>.Type {
print(A.Element.pluralKey)
}
但是控制台的輸出是:
Array<SPTArtist>
false
將第二行更改為
print(T.self is Array<SPTArtist>.Type)
打印true
,但檢查每種可能的類型似乎毫無意義。 當 Element 是繼承自SPTBaseObject
的類時,我只希望它返回 true 。
SPTArtist
是一個繼承自SPTBaseObject
的類。
public class SPTArtist: SPTBaseObject {
...
}
public class SPTBaseObject: Codable {
internal class var pluralKey: String? {
return nil
}
}
編輯:
我的方法看起來像這樣
private class func perform<T>(request: URLRequestConvertible, completion: @escaping (Result<T, Error>) -> Void) where T: Decodable {
AF.request(request).responseData { response in
if let error = response.error {
completion(.failure(error))
}
guard let data = response.value else {
completion(.failure(SPTError.noDataReceivedError))
return
}
if let error = try? JSONDecoder().decode(SPTErrorResponse.self, from: data) {
completion(.failure(error.error))
return
}
// Check if T is an array, if so try to decode a Root<T> object. Here's an error, I cannot construct the Root type like this although the Element is guaranteed to be a SPTBaseObject subclass
if let A = T.self as? Array<SPTBaseObject>.Type,
let root = try? JSONDecoder().decode(Root<A.Element.self>, from: data) {
completion(.success(root.items))
} else if let object = try? JSONDecoder().decode(T.self, from: data) {
completion(.success(object))
} else {
completion(.failure(SPTError.decodingError))
}
}
}
將利用pluralKey
的SPTBaseObject
pluralKey
屬性的Root
類
class Root<T>: Decodable where T: SPTBaseObject {
let items: [T]
private struct CodingKeys: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int?
init?(intValue: Int) {
return nil
}
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
guard let key = T.pluralKey, let codingKey = CodingKeys(stringValue: key) else {
fatalError()
}
items = try container.decode([T].self, forKey: codingKey)
}
}
如果我理解正確,您可以使用一個函數,該函數接受一個[T]
數組,其中T
應該是SPTBaseObject
子類,以及一個只接受一個 T 對象的重載,如下所示:
func getPluralKey<T: SPTBaseObject>(_ array: [T]) {
print(T.pluralKey ?? "nil")
}
func getPluralKey<T: SPTBaseObject>(_ object: T) {
print(T.pluralKey ?? "nil")
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.