Skip to content

Instantly share code, notes, and snippets.

@simplytunde
Last active August 29, 2015 14:12
Show Gist options
  • Save simplytunde/b8391c97b59798c34340 to your computer and use it in GitHub Desktop.
Save simplytunde/b8391c97b59798c34340 to your computer and use it in GitHub Desktop.
Swift:Syntax

#Swift Syntax

Custom Operator

import Foundation

//custom operator
infix operator *** { associativity left }
class Animal:NSObject{
    var  name:String!
    var age:UInt!
    weak var spouse:Animal?
    init(name:String,age:UInt){
        self.name=name
        self.age=age
    }
    func description() ->String{ //to become printable
        return "name= \(name) and age=\(age) spouse=\(spouse)"
    }
}
func ==(a:Animal,b:Animal)->Bool{
    return a.name == b.name && a.age==b.age
}
func *(a:Animal,b:UInt)->Animal{ //multiply the age by number
    let age=a.age * b
    return Animal(name:a.name,age:age)
}
func *(a:UInt,b:Animal)->Animal{
    let age=b.age * a
    return Animal(name:b.name,age:age)
}
//custom operator
func ***(a:Animal,b:Animal){ //This simply means they are married
    a.spouse=b
    //b.spouse=a //This keep crashing the program.y?
}

let dog=Animal(name:"Lucky",age:3)
let cat=Animal(name:"Branson",age:4)
dog *** cat //dog is married to cat
println(cat)
println(dog)
println(dog*3)

Type constraint where clause

protocol Animal{
    var name:String!{get}
    typealias ElementType
    func getSiblings() ->[ElementType]
    func getMother() -> ElementType?
    func getFather() -> ElementType?
    func addSibling(sibling:ElementType)
}
class Human:Animal{
    let name:String!
    let father:Human?
    let mother:Human?
    var siblings:[Human]=[]
    init(name:String,father:Human?=nil,mother:Human?=nil){
        self.name=name
        self.father=father
        self.mother=mother
    }
    func getSiblings()->[Human]{
        return siblings
    }
    func getMother()->Human?{
        return mother?
    }
    func getFather()->Human?{
        return father?
    }
    func addSibling(sibling: Human) {
        siblings.append(sibling)
    }

}
func ==<T:Animal>(a:T,b:T)->Bool{
    return a.name == b.name //Just for simplicity purpose
}

func compareAnimal<T:Animal,Equatable where T.ElementType: Animal>(a:T, b:T)->Bool{
    return a == b
}

let firstMan=Human(name:"Adam")
let firstWoman=Human(name:"Eve")
let firstBorn=Human(name:"Steve",father: firstMan, mother: firstWoman)
println(firstMan == firstWoman)

Associated Type

protocol Animal{
    typealias Element
    func getSiblings() ->[Element]
    func getMother() -> Element?
    func getFather() -> Element?
    func addSibling(sibling:Element)
}
class Human:Animal{
    let name:String!
    let father:Human?
    let mother:Human?
    var siblings:[Human]=[]
    init(name:String,father:Human?=nil,mother:Human?=nil){
        self.name=name
        self.father=father
        self.mother=mother
    }
    func getSiblings()->[Human]{
        return siblings
    }
    func getMother()->Human?{
        return mother?
    }
    func getFather()->Human?{
        return father?
    }
    func addSibling(sibling: Human) {
        siblings.append(sibling)
    }
    
}

let firstMan=Human(name:"Adam")
let firstWoman=Human(name:"Eve")
let firstBorn=Human(name:"Steve",father: firstMan, mother: firstWoman)

Generics

func printEqual<T:Equatable>(a:T,b:T){
    if a == b{
        println("\(a) && \(b) are equal")
    }else{
        println("\(a) && \(b) are not equal")
    }
}
printEqual(1,1)

Optional Chaining

class Person{
    let name:String!
    let age:UInt!
    var phone:PhoneNumber?
    init(name:String,age:UInt){
        self.name=name
        self.age=age
    }    
}
class PhoneNumber{
    var carrier:String
    var number:String
    init(number:String,carrier:String){
        self.number=number
        self.carrier=carrier
    }
    func phoneNumber()->String{
        return number
    }
}

let jacksparrow=Person(name:"Jack Sparrow",age:32)
//If you comment next line out, it does crash.It only return nil
jacksparrow.phone=PhoneNumber(number:"580-581-CAPTAIN",carrier:"Black Pearl")
let number=jacksparrow.phone?.number
let carrier=jacksparrow.phone?.phoneNumber()

println(number)
println(carrier)

Strong Reference Cycle

class DistanceRun{
    let miles:Double!
    lazy var kilometers:()->Double={
         [unowned self] in //The auto capture self, use owned to avoid strong cycle
              return (self.miles * 1.60934)
    }
    init(miles:Double){
        self.miles=miles
    }
    deinit{
        println("Object is being deallocated")
    }
}

var distanceRun:DistanceRun?=DistanceRun(miles:2)
println(distanceRun!.kilometers())
distanceRun=nil
//use unowned var administrator:Person or weak var school:School?  to break the cycle
//unowned is used if reference can never be nil once initialized else use use weak.
class School{
    let name:String!
    var administrator:Person //use owned to break the cycle 
    init(name:String,administrator:Person){
        self.name=name
        self.administrator=administrator
    }
    deinit{
        println("school: \(name)  is being deallocated")
    }
}
class Person{
    let name:String!
    let age:UInt!
    weak var school:School? //or use weak to break the cycle
    init(name:String,age:UInt){
        self.name=name
        self.age=age
    }
    deinit{
        println("person: \(name) is being deallocated")
    }
}
var president:Person?=Person(name:"Drew Gilpin Faust",age:67)
var harvard:School?=School(name:"Harvard University",administrator:president!)
president!.school=harvard //This created string reference cycle
president=nil //if you comment this out only one line will be printed
harvard=nil  //if you comment this out, none will be printed

Failable Initializer

class FileResource{
    let resourceLocation:String!
    init?(location:String){
        if !locationValid(location){
            return nil
        }
        resourceLocation=location
    }
    func locationValid(location:String)->Bool{
        //Implement the algorithm to check if location is valid
        return false //or you might return true
    }
}

if let fileResource=FileResource(location:"a"){
    println("Valid resource created")
}else{
    println("Resource could not be created")
}

Enum associated values

enum Nationality{
    case American(Int) //SSN for identification
    case British(Int,String) //passport,name
    case SouthAfrican(Int,String,UInt) //password,name,age
}

let person=Nationality.American(1234)
switch person{
    case let .American(ssn):
      println("American with SSN = \(ssn)")
    case let .British(passport,name):
      println("British citizen with password = \(passport) & name = \(name)")
    case let .SouthAfrican(passport,name,age):
      println("South African with name=\(name) & age=\(age) & passport = \(passport)")
}

Switch case where clause

let person=("jesus",20)

switch person{
    case let(name,age) where name == "jesus":
        println("This is baby jesus")
    case let(name,age):
        println("Name is \(name)")
}

Nil Coalescing Operator

var color:String?
var defaultColor:String="White"

let colorOption=color ?? defaultColor

println(colorOption)

Hashable Protocol

class Person:Hashable{
     var name:String?
     var age:UInt?
     init(name:String,age:UInt){
          self.name=name
          self.age=age
     }
     var hashValue:Int{
         return "\(name),\(age)".hashValue
     }
}

func ==(lhs:Person,rhs:Person)->Bool{ //You must conform to Equatable protocol
    return lhs.hashValue == rhs.hashValue
}

if Person(name:"a",age:18) == Person(name:"a",age:18){
    println("Equal yes")
}else{
    println("Not equal")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment