user2984842
user2984842

Reputation: 81

Swift anomalies between Any and AnyObject

I've been playing around with Swift. I am trying to create an array containing known different types of Swift vars.

I can get most of the way there with an Array of Any or an Array of AnyObject -- but neither does the complete job. I've found some anomalies -- but I don't know if they are bugs or features.

Here's the code to create and test the arrays:

import UIKit
import Foundation

var aA: Array = [Any]()
aA.append("a String")          // Defaults to String
aA.append(123)                 // Defaults to Int
aA.append(-456.00)             // Defaults to Double
aA.append(0.33 as Float)       // Must cast as Float
aA.append(false)               // Defaults to Bool
aA.append("C" as Character)    // Must cast as Character

println("\naA: \(aA)\n")
(aA[0] is String)    ? println("aA[0] is String:    \(aA[0])") : println("aA[0] is Not String: \(aA[0])")
(aA[1] is Int)       ? println("aA[1] is Int:       \(aA[1])") : println("aA[1] is Not Int:    \(aA[1])")
(aA[2] is Double)    ? println("aA[2] is Double:    \(aA[2])") : println("aA[2] is Not Double: \(aA[2])")
(aA[3] is Float)     ? println("aA[3] is Float:     \(aA[3])") : println("aA[3] is Not Float:  \(aA[5])")
(aA[4] is Bool)      ? println("aA[4] is Bool:      \(aA[4])") : println("aA[4] is Not Bool:   \(aA[4])")
(aA[5] is String)    ? println("aA[5] is String:    \(aA[5])") : println("aA[5] is Not String: \(aA[5])")
(aA[5] is Character) ? println("aA[5] is Character: \(aA[5])") : println("aA[5] is Not Character: \(aA[5])")

var aO = [AnyObject]()
aO.append("a String")          // Defaults to String
aO.append(123)                 // Defaults to Int
aO.append(-456.00)             // Defaults to Double
aO.append(0.33)                // Defaults as Float
aO.append(false)               // Defaults to Bool
aO.append("C")                 // Defaults to String -- Cannot cast as Character

println("\naO: \(aO)\n")
(aO[0] is String) ? println("aO[0] is String: \(aO[0])") : println("aO[0] is Not String: \(aO[0])")
(aO[1] is Int)    ? println("aO[1] is Int:    \(aO[1])") : println("aO[1] is Not Int:    \(aO[1])")
(aO[2] is Double) ? println("aO[2] is Double: \(aO[2])") : println("aO[2] is Not Double: \(aO[2])")
(aO[3] is Float)  ? println("aO[3] is Float:  \(aO[3])") : println("aO[3] is Not Float:  \(aO[5])")
(aO[4] is Bool)   ? println("aO[4] is Bool:   \(aO[4])") : println("aO[4] is Not Bool:   \(aO[4])")
(aO[5] is String) ? println("aO[5] is String: \(aO[5])") : println("aO[5] is Not String: \(aO[5])")


/*

Anomalies between Any and AnyObject

aA[2] -456.00 Double returns -456.0 ................... aO[2] -456.00 Double returns -456
aA[3] 0.33 Must cast as Float ......................... aO[3] 0.33 defaults to Float
aA[3] 0.33 Float returns 0.330000013113022 ............ aO[3] 0.33 Float returns 0.33
aA[4] false Bool returns false ........................ aO[4] false Bool returns 0
aA[5] "C" Defaults to String must cast as Character ... aO[5] "C" Defaults to String -- Cannot cast as Character
aA[5] "C" Character returns Character ................. aO[5] "C" Defaults to String -- Cannot Test for Character

*/

The anomalies are shown as comments (above).

Here's the Playground output:

aA: [a String, 123, -456.0, 0.330000013113022, false, C]

aA[0] is String:    a String
aA[1] is Int:       123
aA[2] is Double:    -456.0
aA[3] is Float:     0.330000013113022
aA[4] is Bool:      false
aA[5] is Not String: C
aA[5] is Character: C

aO: [a String, 123, -456, 0.33, 0, C]

aO[0] is String: a String
aO[1] is Int:    123
aO[2] is Double: -456
aO[3] is Float:  0.33
aO[4] is Bool:   0
aO[5] is String: C

Upvotes: 1

Views: 320

Answers (1)

drewag
drewag

Reputation: 94733

The anomalies you are seeing are because there is some implicit conversion happening between the basic Swift types and the basic Objective-C types. In Swift for example, String is a struct and therefore cannot be added to an AnyObject array. However, because you are importing Foundation, it is being implicitly cast to NSString which is a class and therefore can be added to an AnyObject array.

Character on the other hand, does not have a conversion to a class available in Foundation.

I wrote more about this in a blog post a little while back.

Upvotes: 2

Related Questions