Можете ли вы определить, является ли данный T.Type массивом или словарем? - PullRequest
2 голосов
/ 25 января 2020

Написание некоторых удобных методов для библиотеки JSON, над которой я работаю. У нас есть функция, которая принимает Codable. Внутри я пытаюсь определить, является ли это массив, объект (словарь) или просто значение Codable самостоятельно.

Попробовал это, но все варианты Codable возвращают 'Codable' ...

func check<T>(_:T.Type) {

    print("\(String(describing:T.self)) is ", terminator:"")

    switch T.self {

        case _ where T.self is Array<Codable>.Type:
            print("CodableArray")

        case _ where T.self is Dictionary<String, Codable>.Type:
            print("StringCodableDictionary")

        case _ where T.self is Codable.Type:
            print("Codable!")

        default:
            print("Not codable")
    }
}

class CodableThing : Codable {}
class NonCodableThing {}

check(CodableThing.self)
check([CodableThing].self)
check([String:CodableThing].self)
check(NonCodableThing.self)
check([NonCodableThing].self)
check([String:NonCodableThing].self)

Вывод ...

CodableThing is Codable!
Array<CodableThing> is Codable!
Dictionary<String, CodableThing> is Codable!
NonCodableThing is Not codable
Array<NonCodableThing> is Not codable
Dictionary<String, NonCodableThing> is Not codable

Итак, как вы обнаруживаете первые два случая?

Попытка # 2

Ограничение T только взять Codables, как я могу просто проверить, является ли это словарь, массив или что-то еще? (Обратите внимание, что это не компилируется)

func check<T:Codable>(_:T.Type) {

    print("\(String(describing:T.self)) is ", terminator:"")

    switch T.self {

        case _ where T.self is Array.Type:
            print("CodableArray")

        case _ where T.self is Dictionary.Type:
            print("CodableDictionary")

        default:
            print("Codable")
    }
}

class CodableThing : Codable {}

check(CodableThing.self)
check([CodableThing].self)
check([String:CodableThing].self)
...