Data

Last updated on October 3rd, 2023

Built-In Types

These are the types available by default  in the Swift language. Please note that these are not “primitive” data  types in the strict sense, as available in other languages. Integer, Real, Boolean, Character and String are actually nothing but Structs. Similarly Array and Dictionary are templatized (generic) Structs. There is no data type named Tuple as such. Each tuple object is an instance of its own unique definition, which is just a group of values of same/different data types, treated as a single entity.

Integer

  • Int8, Int16, Int32, Int64 – For 8 bit, 16 bit, 32 bit and 64 bit signed integer numbers.
  • UInt8, UInt16, UInt32, UInt64 – For 8 bit, 16 bit, 32 bit and 64 bit unsigned integer numbers.
  • Int – For signed integers. It is Int32 in a 32 bit platform and Int64 in a 64 bit platform.
  • UInt – For unsigned integers. It UInt32 in a 32 bit platform and UInt64 in a 64 bit platform.
  • Unless really required, it is advised to use Int type for integral values as much as possible even if the data range is small or non-negative.
  • To get the minimum and maximum values that the integer type can contain use min and max methods.
let minValue = Int.min
let maxValue = UInt.max

Real

  • Float – For 32 bit real number, precision at least 6 decimal digits.
  • Double – For 64 bit real number, precision at least 15 decimal digits.

Boolean

  • Bool – Can have values true or false.
let isVisible: Bool = false
  • Unlike in C/C++ languages, true and false do not correspond to numeric values 1 and 0.

Character

  • For single character values.
let starSymbol: Character = "*"

String

  • For a string of characters.
let emptyString: String = String()
let helloString: String = "Hello"
  • String interpolation allows substituting constants, variables etc in the string.
let fileCount = 10
let statusMessage = "Downloaded \(fileCount) files"
  • String can contain escaped special characters \0 , \\ , \t , \n , \r , \” and \’
  • Unicode character can be added like “\u{value}” where value is the hexadecimal value. This can also be extended as “\u{value1}\u{value2}” which represents a single character, combining 2 symbols. These are called extended grapheme clusters.

Array

  • Arrays are ordered list of items belonging to common data type.
let arrayName: Array<ElementDataType>  // Full syntax. arrayName is an immutable array
// of objects belonging to ElementDataType

var arrayName: [ElementDataType]      // Shorthand syntax. arrayName is a mutable
                                    // array of objects belonging to ElementDataType
  • Examples (You can interchangeably use Array<DataType> in place of [DataType] below

var songList: [String]                                // Null reference to string array
var songList: [String] = [String]()  // Empty string array
var songList: [String] = []

var songList = [String]()            // Automatic type inference
var songList = [String](arrayLiteral: "abc", "def") // String array with 2 elements
var songList = ["abc", "def"] // Same as above

var songList = [String](count: 2, repeatedValue: "a")
var songList = anotherSongList // Array copy. Both point to
// different memory locations

var songList = rockList + popList // songList now contains all
// rockList elements followed by
// all popList elements

var digits = [Int](0...9) // Array containing 10 elements
// from 0 to 9. "..." is one of
// the range operators which will
// be discussed later
  • Mutability of array depends on whether it is a constant or variable. An immutable array does not allow you to change the size or contents once it is created.

Dictionary

Tuple

  • It is a type with multiple sub values each of which can be of a different type.
let patientDetails: (String, Int, Double) = (name: "Sam", age: 42, height: 5.8)
                          Or
let patientDetails = (name: "Sam", age: 42, height: 5.8)    // Automatic type inference
  • Extracting individual values from the tuple patientDetails
let patientName: String = patientDetails.name
let patientAge: Int = patientDetails.age
let patientHeight: Double = patientDetails.height
  • Elements can also be accessed using their index numbers, starting from 0
let patientName = patientDetails.0
let patientAge = patientDetails.1
let patientHeight = patientDetails.2
  • Instead of above 3 lines, we can use the following single line of code
let (patientName, patientAge, patientHeight) = patientDetails
  • Unwanted elements can be ignored by substituting with an underscore.
let (patientName, _, patienHeight) = patientDetails
  • It is not mandatory to name the elements.
let patientDetails = ("Sam", 42, 5.8)
  • Use tuples for temporarily grouping multiple values (for example return multiple values from a function). For a more permanent grouping of complex data, use Structs or Classes.

Custom Types

Swift supports the following mechanisms  to create custom types. Please note that they themselves are not Types,  but just keywords to define your own types. As discussed above, all the  built-in types except Tuple are nothing but different types of Structs.

Class

Struct

Enum

Nesting of Types

  • Swift allows you to nest the definitions of classes, structs and enums inside other classes, structs or enums.
class Nest {
struct Bird {
enum Gender {
case MALE
case FEMALE
}

var name: String
var gender: Gender
}

var bird: Bird

init(bird: Bird) {
self.bird = bird
}
}

let myBird = Nest.Bird(name: "Doodu", gender: Nest.Bird.Gender.FEMALE)
var newNest = Nest(bird: myBird)
  • Nesting can be done as many levels deep as required.
  • You can refer to the nested entities by prefixing their name with that of the outer entities in order using dot syntax.
Eg: Nest.Bird.Gender.FEMALE

Type Safety

  • Swift is a type safe language and performs type checks at the compilation time itself.

Type Inference

  • If the data type is not explicitly mentioned, Swift tries to automatically infer the type wherever possible.
  • By default integral numbers are treated as Int and real numbers are treated as Double.
  • Examples
let a = 10           // 10 is considered Int
let b = 5.6 // 5.6 is considered Double
let c = "Hello" // "Hello" is a String
let d = true // true is Boolean
let e = 2 + 1.14 // 2, 1.14 and the result are Double

Type Conversion

  • Conversion between different types needs to be done explicitly in Swift.
let intValue = 3
let doubleValue = Double(intValue) // This actually invokes a parameterized constructor
// of the Double struct, which accepts an integer
let doubleRadius = 5.6
let intRadius = Int(5.6) // This always results in truncation
// 5.6 becomes 5, -5.6 becomes -5
  • For type conversion to work, the target data type should have a constructor that accepts a parameter of the source data type

Type Casting

  • Type casting is used to treat an object as if it is belonging to a super/sub class in its own hierarchy.
object as SuperType            // Syntax, "as" is the type casting operator

let myCat = Cat() // myCat is an instance of Cat, inherited from Animal
let myAnimal = myCat as Animal // myAnimal is a reference of type Animal to the
// instance of myCat.
  • For conditional downcasting use as?, which returns an optional reference either pointing to the instance or nil depending on whether the casting was successful or not.
  • The forceful downcasting operator as! attempts forceful casting, which on failure throws run time error.
object as? SubType              // Syntax, "as?" performs conditional downcasting
object as! SubType // Syntax, "as!" performs forceful downcasting

let myCat = myAnimal as? Cat // myCat is created as a Cat? type
let myDog = myAnimal as! Dog // this results in runtime error since myAnimal is not a Dog
  • Optional casting can be used to check the type of an instance as well as conformance to protocol.
if let myCat = petAnimal as? Cat {
myCat.meow()
}
  • Type casting does not modify the object instance in any manner.

Type Checking

  • The type checking operator is can be used to test if an instance is of a certain subclass type.  It returns true or false to indicate the result of the check.
if myCat is Cat {    print("It is a Cat!")
}

Type Alias

  • Defines alternate name for an existing type
typealias Speed = Double        // Speed is now an alias for Double
let vehicleSpeed: Speed = 100

 

Leave a Reply

Your email address will not be published. Required fields are marked *