簡體   English   中英

Swift 泛型。 如何檢查數組元素的類型是否繼承自其他類

[英]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))
        }
    }
}

將利用pluralKeySPTBaseObject 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM