0

In my generic method I want to check if T is an array. During testing I'm calling the method for T type of [SPTArtist]. If I print the type of T it shows:

Array<SPTArtist>

And if I check if it's an Array of SPTArtist it returns true.

print(T.self is Array<SPTArtist>.Type) //true

But the code

print(T.self is Array<Any>.Type) //false

prints false

Shouldn't it be true as all objects are Any?

Adam
  • 1,776
  • 1
  • 17
  • 28
  • I already answered this earlier. Watch your comments! –  Oct 07 '20 at 07:15
  • 1
    Does this answer your question? [Swift generics. How to check if the type of Array's Element inherits from other class](https://stackoverflow.com/questions/64223349/swift-generics-how-to-check-if-the-type-of-arrays-element-inherits-from-other) –  Oct 07 '20 at 07:16
  • I don't think it helps in my situation – Adam Oct 07 '20 at 07:21
  • I think it’s a complete explanation. What do you find lacking? –  Oct 07 '20 at 07:35

1 Answers1

0

While it is true that you can assign any value (not just objects) to a variable of type Any and you can add any value to an array whose element type is Any, it is not true that [Any] and [SPTArtist] are the same type.

You can see this from the following example:

var someArray = [Any]()
var someOtherArray = [SPTArtist]()

let artist = SPTArtist()

someArray.append(artist)      // OK
someOtherArray.append(artist) // OK

someArray.append(1)           // OK
someOtherArray.append(1)      // Error

Your test is checking to see if the type of T is literally [Any], not if it is "an array".

If you search you can find several variations on checking to see if a variable is an array.

This answer that extends Array with an empty protocol seems like a reasonable approach.

You could add a type constraint so that it only applies to arrays of your type:

protocol ArrayType {}
extension Array: ArrayType where Element == SPTArtist {}  

func isArray() -> Bool {
    return T.self is ArrayType.Type  // Returns true iff T is [SPTArtist]
}
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • Explain that you understand the covariance problem or this will haunt you to the grave and beyond! –  Oct 07 '20 at 11:19
  • I am not sure which part you are specifically referring to. The problem here isn't related to covariance, since `Any` is not a super type. The OP's problem is that `[Any]` is a specific type, i.e. it is literally "an Array of `Any`" which is different to `[SPTArtist]`. Now of course an `[SPTArtist]` can contain elements of some subclass of `SPTArtist`, but that doesn't change the fact the array must be an array of `SPTArtist` for the `isArray` function to return `true`. An array of `SPTArtistSubClass` won't return `true` unless the extension is also applied to that element type – Paulw11 Oct 07 '20 at 11:44