//: Playground – noun: a place where people can play
// DataStructure (function, optional, enum, class, inheritance, struct)
// Kyoung Shin Park (2016 Fall)
import Cocoa
// function
func sayHello(personName: String = “World”) -> String {
let greeting = “Hello, ” + personName + “!”
return greeting
}
var delegate = sayHello()
print(sayHello())
print(sayHello(“Anna”))
print(delegate)
// Optional & Forced unwrapping & Optional binding
let planets = [“Mercury”:1, “Venus”:2, “Earth”:3] // assign dictionary
let planetID: Int? = planets[“Earth”]
if planetID != nil { // check if planetID is nil to prevent run-time error
print(“Earth = \(planetID!)”) // Forced unwrapping (using !) Earth = 3
} else {
print(“Earth is not found”)
}
// Optional binding (unwrapping an optional)
if let planetID = planets[“Earth”] { // return true if planetID has valid value
print(“Earth = \(planetID)”) // Earth = 3
}
// ImplicitlyUnwrappedOptional
var w: Int! = 1 // same as var w: ImplicitlyUnwrappedOptional<Int> = 1
print(w) // you don’t need to put !
var z: Int! // same as var z: ImplicitlyUnwrappedOptional<Int> = nil
//print(z) // RUN-TIME ERROR (because z is nil)
w = nil // OK
//print(w) // RUN-TIME ERROR (because w is nil) while unwrapping
// Nil coalescing operator
let defaultColorName = “Red”
var userDefinedColorName: String? // set to nil
// colorNameToUse = “Red” (because userDefinedColorName = nil)
var colorNameToUse = userDefinedColorName ?? defaultColorName
// if planets[“Earth”] = nil then it will return the default value 0)
var ID : Int? = planets[“Earth”] ?? 0 // var earthID: Int? = 3
// Optional chaining
class Person {
var contact: Contact? // automatically set to nil
}
class Contact {
var address: String? // automatically set to nil
var telephone: String? // automatically set to nil
}
let p = Person()
//var phone = p.contact!.telephone! // run-time error(because contact=nil)
if let contact = p.contact { // optional binding to read optional property
if let phone = contact.telephone {
print(phone)
} else {
print(“phone is nil”)
}
} else {
print(“contact is nil”)
}
// optional chaining
var phone = p.contact?.telephone // phone=nil (because contact=nil)
print(phone)
// use optional chaining & optional binding together
p.contact = Contact()
p.contact?.telephone = “12345”
if let phone = p.contact?.telephone {
print(p.contact?.telephone)
}
// Enumeration
enum Gender {
case Female
case Male
init() { // initialization
self = .Female
}
init(_ name: String)
{
switch name {
case “Female”, “여자”: self = .Female
case “Male”, “남자”: self = .Male
default: self = .Female
}
}
var description: String {
switch self {
case .Female: return “FEMALE~”
case .Male: return “MALE~”
}
}
}
var gender = Gender()
print(gender.description)
gender = Gender(“남자”)
print(gender.description)
gender = Gender.Female
gender = .Male
print(Gender.Male.description)
switch gender {
case .Female: print(“FEMALE!!”)
case .Male: print(“MALE!!”)
}
// Enum, multiple member values can appear on a single line, separated by commas
// Enum rawValue
enum Planet: Int {
case Mercury=1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
let earthID = Planet.Earth.rawValue
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
print(“Mostly harmless”)
default:
print(“Not a safe place for humans”)
}
let aPlanet = Planet(rawValue: 7)
switch aPlanet! {
case .Earth:
print(“Mostly harmless”)
default:
print(“Not a safe place for humans”)
}
if let possiblePlanet = Planet(rawValue: 9) {
switch possiblePlanet {
case .Earth:
print(“Mostly harmless”)
default:
print(“Not a safe place for humans”)
}
} else {
print(“There isn’t a planet at position 9”)
}
// Enum associated values
enum TrainStatus {
case OnTime
case Delayed(Int)
}
var status:TrainStatus = .Delayed(5)
status = .OnTime
switch status {
case .OnTime:
print(“Train is on time”)
case .Delayed(let minutes):
print(“Train is delayed by \(minutes) minutes”)
}
// class
class Vehicle {
// stored properties
var numberOfPassengers: Int = 2
var numberOfWheels: Int = 4
// computed properties
var NumberOfWheels: Int {
get { return numberOfWheels }
set { numberOfWheels = newValue }
}
var description: String {
return “\(numberOfWheels) number of wheels”
}
}
class Bicycle: Vehicle {
override init() {
super.init()
numberOfPassengers = 1
numberOfWheels = 2
}
}
class Car: Vehicle {
// stored properties
var minVelocity: Int = 30
var accelVelocity: Int = 10
// computed properties
var speed: Int {
get {
return minVelocity + accelVelocity
}
set(newVelocity) {
accelVelocity = newVelocity – minVelocity
}
}
}
// struct
struct Frame {
var x: Int, y: Int // stored property
var width: Int, height: Int // stored property
var area: Int { // computed property (don’t need to enclose getter)
return width * height
}
mutating func addWidth(width: Int) {// method
self.width += width // mutating modifies the value of a stored property
}
}
let f = Frame(x: 5, y: 10, width: 100, height: 100) // member-wise initializer
//f.width = 250 // invalid (can’t change the struct properties stored in a let)
var g = Frame(x: 5, y: 10, width: 100, height: 100)
g.addWidth(15) // use mutating func to modify the value of a stored property
print(g.width) // 15
let h = Frame(x: 5, y: 10, width: 100, height: 100)
//h.addWidth(15) // compile error (can’t call mutating func of struct stored in a let)