I want to check whether the generic class type is an Array:
func test<T>() -> Wrapper<T> {
let isArray = T.self is Array<Any>
...
}
But it warns
Cast from 'T.type' to unrelated type 'Array' always fails
How can I solve this problem?
added: I've uploaded my codes to Gist. https://gist.github.com/nallwhy/6dca541a2d1d468e0be03c97add384de
What I want to do is to parse json response according to it's an array of model or just one model.
– Using Object Array In the above code demonstration, A generic class array is defined. The object array is a member of the class, instantiated with a constructor and a length variable. The generic getter and setter methods are used to read and set an array element of a particular type.
Array#newInstance to initialize our generic array, which requires two parameters. The first parameter specifies the type of object inside the new array. The second parameter specifies how much space to create for the array.
As commentator @Holex says, you can use Any
. Combine it with Mirror
and you could, for example, do something like this:
func isItACollection(_ any: Any) -> [String : Any.Type]? {
let m = Mirror(reflecting: any)
switch m.displayStyle {
case .some(.collection):
print("Collection, \(m.children.count) elements \(m.subjectType)")
var types: [String: Any.Type] = [:]
for (_, t) in m.children {
types["\(type(of: t))"] = type(of: t)
}
return types
default: // Others are .Struct, .Class, .Enum
print("Not a collection")
return nil
}
}
func test(_ a: Any) -> String {
switch isItACollection(a) {
case .some(let X):
return "The argument is an array of \(X)"
default:
return "The argument is not an array"
}
}
test([1, 2, 3]) // The argument is an array of ["Int": Swift.Int]
test([1, 2, "3"]) // The argument is an array of ["Int": Swift.Int, "String": Swift.String]
test(["1", "2", "3"]) // The argument is an array of ["String": Swift.String]
test(Set<String>()) // The argument is not an array
test([1: 2, 3: 4]) // The argument is not an array
test((1, 2, 3)) // The argument is not an array
test(3) // The argument is not an array
test("3") // The argument is not an array
test(NSObject()) // The argument is not an array
test(NSArray(array:[1, 2, 3])) // The argument is an array of ["_SwiftTypePreservingNSNumber": _SwiftTypePreservingNSNumber]
Try out define an array marker protocol. Refer to this answer.
protocol AnyTypeOfArray {}
extension Array: AnyTypeOfArray {}
extension NSArray: AnyTypeOfArray {}
func isArray<T>(type: T.Type) -> Bool {
return T.self is AnyTypeOfArray.Type
}
print(isArray(type: [String].self)) // true
print(isArray(type: String.self)) // false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With