Reputation: 1571
Is there a function to determine the variable type in Swift? I presume there might be something like like type()
in Python.
I'd like a way to judge if a variable is a Foundation object or C variable in Swift. Like NSString vs String, or NSArray vs array. So that I can log it out in console and see clearly what it is.
For example, I would like to know the type inferred for the the first array
below:
var array = [1,2,3] // by default NSArray or array?
var array:[Int] = [1,2,3]
var array:NSArray = [1,2,3]
var array:Array<Any> = [1,2,3]
I have seen answers for judging if a given variable is a kind of given type in this question, but I'll say it's quite different from what I want to ask.
Upvotes: 38
Views: 33431
Reputation: 6196
Someone mentioned this above, but I think it deserves visibility as an answer rather than a comment. You can now simply use type(of: ___):
var red, green, blue: Double
print(type(of: green))
yields
Double
Upvotes: 9
Reputation: 129735
You can get a reference to the type object of a value by using the .dynamicType
property. This is equivalent to Python's type()
function, and is mentioned in the Swift documentation under Language Reference: Types: Metatype Type.
var intArray = [1, 2, 3]
let typeOfArray = intArray.dynamicType
With this type object, we are able to create a new instance of the same array type.
var newArray = typeOfArray()
newArray.append(5)
newArray.append(6)
println(newArray)
[5, 6]
We can see that this new value is of the same type ([Int]
) by attempting to append a float:
newArray.append(1.5)
error: type 'Int' does not conform to protocol 'FloatLiteralConvertible'
If we import Cocoa and use an array literal with mixed types, we can see that an NSArray
is created:
import Cocoa
var mixedArray = [1, "2"]
let mixedArrayType = mixedArray.dynamicType
var newArray = mixedArrayType()
var mutableArray = newArray.mutableCopy() as NSMutableArray
mutableArray.addObject(1)
mutableArray.addObject(1.5)
mutableArray.addObject("2")
println(mutableArray)
(1, "1.5", 2)
However, at this point there does not seem to be any general way to generate a string description of a type object, so this may not serve the debugging role that you were asking about.
Types derived from NSObject
do have a .description()
method, as is used in SiLo's answer,
println(mixedArrayType.description())
__NSArrayI
However this is not present on types such as Swift's built-in arrays.
println(typeOfArray.description())
error: '[Int].Type' does not have a member named 'description'
Upvotes: 26
Reputation: 357
I use breakpoints during debuging but if you need to check if they match a certain type during runtime then drewag is right
another thing you can do is test datatype with assertion this would only work in debugging but with assertion you can set conditions which if met app crashes
maybe something like assert(let tArray == oldArray as? NSArray[] //if not NSArray app crashes)
Upvotes: 0
Reputation: 12858
It is possible to do so, though it's not necessarily that easy nor useful:
func getClassName(obj : AnyObject) -> String
{
let objectClass : AnyClass! = object_getClass(obj)
let className = objectClass.description()
return className
}
let swiftArray = [1, 2, 3]
let swiftDictionary = ["Name": "John Doe"]
let cocoaArray : NSArray = [10, 20, 30]
var mutableCocoaArray = NSMutableArray()
println(getClassName(swiftArray))
println(getClassName(swiftDictionary))
println(getClassName(cocoaArray))
println(getClassName(mutableCocoaArray))
Output:
_TtCSs22ContiguousArrayStorage00007F88D052EF58
__NSDictionaryM
__NSArrayI
__NSArrayM
You are better of using the is
and as
keywords in Swift. Many foundation classes use class clusters (as you can see with __NSArrayI
(immutable) and __NSArrayM
(mutable).
Notice the interesting behavior. The swiftArray
defaults to using a Swift Array<Int>
while the swiftDictionary
defaulted to NSMutableDictionary
. With this kind of behavior I would not really rely on anything being a certain type (check first).
Upvotes: 10