Created
June 13, 2014 18:09
-
-
Save drtoast/15f25dc4d7097f69673f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Playground - noun: a place where people can play | |
// https://developer.apple.com/library/prerelease/ios/navigation/index.html | |
import Cocoa | |
// variables | |
var string = "Hello, playground" | |
let float = 15.5 // implicit | |
let explicitFloat: Float = 15.5 | |
var sentence = "\(string) \(explicitFloat)" | |
var int = 0 | |
var things = ["a", "b", 3] | |
things[0] | |
// optionals | |
var optionalString: String? = "hello" | |
optionalString = "oops" | |
if optionalString { | |
string = "yeppers" | |
} else { | |
string = "nope" | |
} | |
// dictionaries | |
var dict = ["foo": "bar", "baz": "quux"] | |
dict["foo"] | |
var result = String() | |
for (k,v) in dict { | |
"\(k) is \(v)" | |
if k == "foo" { | |
string = "yep" | |
} | |
string | |
} | |
// arrays | |
var a = [1, 2, 3] | |
var b = a // by reference until length is changed | |
a[1] = 9 | |
a // [1,9,3] | |
b // [1,9,3] | |
a.append(4) // array copied here | |
a // [1,9,3,4] | |
b // [1,9,3] | |
var c = a.copy() // explicit copy | |
// functions | |
func greet(name: String, day: String) -> String { | |
return "Hello \(name), today is \(day)." | |
} | |
greet("Bob", "Tuesday") | |
// tuples | |
func getGasPrices() -> (Double, Double, Double) { | |
return (3.59, 3.69, 3.79) | |
} | |
getGasPrices() | |
let numbers = [1,2,3] | |
numbers.map({number in 3 * number}) | |
sort([1, 5, 3, 12, 2]) { $0 > $1 } | |
// classes | |
class Shape { | |
var numberOfSides = 0 | |
var name: String? | |
init(name: String) { | |
self.name = name | |
} | |
func simpleDescription() -> String { | |
return "A shape with \(numberOfSides) sides" | |
} | |
} | |
let shape = Shape(name: "hexathing") | |
shape.numberOfSides = 1 | |
shape.simpleDescription() | |
let otherShape = shape | |
otherShape === shape // reference type | |
// structures | |
// (value type: always copied when passed) | |
// (receive a default memberwise initializer) | |
struct Resolution { | |
var width = 0 | |
var height = 0 | |
} | |
class VideoMode { | |
var resolution = Resolution() | |
var name: String? | |
} | |
var someVideoMode = VideoMode() | |
someVideoMode.resolution.width = 1280 | |
string = "The width of someVideoMode is \(someVideoMode.resolution.width)" | |
let vga = Resolution(width: 640, height: 480) // initializer | |
var cinema = vga // copied | |
cinema.width = 1920 | |
cinema.height = 1080 | |
vga // not changed | |
// METHODS | |
// method external parameter names | |
class Counter { | |
var count: Int = 0 | |
// "amount" is local only, numberOfTimes is local and external | |
func incrementBy(amount: Int, numberOfTimes: Int) { | |
count += amount * numberOfTimes | |
} | |
// "amount" is local and external, "times" is external | |
func increment(#amount: Int, times numberOfTimes: Int) { | |
count += amount * numberOfTimes | |
} | |
} | |
let counter = Counter() | |
counter.incrementBy(5, numberOfTimes: 3) | |
counter.increment(amount: 5, times: 3) | |
// mutating methods (modifying value types within instance methods) | |
struct Pointier { | |
var x = 0.0, y = 0.0 | |
mutating func move(x deltaX: Double, y deltaY: Double) { | |
x += deltaX | |
y += deltaY | |
} | |
} | |
var pointier = Pointier(x: 1.0, y: 1.0) | |
pointier.move(x: 2.0, y: 3.0) | |
pointier.x // 3.0 | |
pointier.y // 4.0 | |
// type methods (like class methods) | |
class AnotherClass { | |
class func someTypeMethod() -> String { | |
return "hello" | |
} | |
} | |
AnotherClass.someTypeMethod() | |
// self | |
struct Pointy { | |
var x = 0.0, y = 0.0 | |
func isToTheRightOfX(x: Double) -> Bool { | |
// disambiguate between method parameter and instance property | |
return self.x > x | |
} | |
} | |
let somePoint = Pointy(x: 4.0, y: 5.0) | |
if somePoint.isToTheRightOfX(1.0) { | |
string = "yep" | |
} | |
enum TriStateSwitch { | |
case Off, Low, High | |
mutating func next() { | |
switch self { | |
case Off: | |
self = Low | |
case Low: | |
self = High | |
case High: | |
self = Off | |
} | |
} | |
} | |
var ovenLight = TriStateSwitch.Low | |
ovenLight.next() // .High | |
ovenLight.next() // .Off | |
// ENUMERATIONS | |
// enumeration values | |
enum CompassPoint { | |
// member values with type CompassPoint: | |
case North | |
case South | |
case East | |
case West | |
} | |
var point = CompassPoint.North | |
switch point { | |
case .North: | |
string = "north" | |
case .South: | |
string = "south" | |
default: | |
string = "something" | |
} | |
point = .East | |
// enumeration associated values: | |
enum Barcode { | |
case UPCA(Int, Int, Int) | |
case QRCode(String) | |
} | |
var productBarcode = Barcode.UPCA(8, 85909_51226, 3) | |
productBarcode = .QRCode("ABCDEFG") | |
switch productBarcode { | |
case let .UPCA(numberSystem, identifier, check): | |
string = "UPC-A with value of \(numberSystem), \(identifier) etc" | |
case let .QRCode(productCode): | |
string = "QR code with value of \(productCode)" | |
} | |
// enumeration default values (raw values) | |
enum ASCIIControlCharacter: Character { | |
case Tab = "\t" | |
case LineFeed = "\n" | |
case CarriageReturn = "\r" | |
} | |
enum Planet: Int { | |
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune | |
} | |
let earthOrder = Planet.Earth.toRaw() | |
let optionalPlanet = Planet.fromRaw(7) // returns optional Planet | |
if let planet = optionalPlanet { // must unwrap optional | |
switch planet { | |
case .Earth: | |
string = "Mostly Harmless" | |
default: | |
string = "Not for humans" | |
} | |
} else { | |
string = "not a planet" | |
} | |
// PROPERTIES | |
// stored properties | |
struct FixedLengthRange { | |
var firstValue: Int // variable stored property | |
let length: Int // constant stored property | |
} | |
var range = FixedLengthRange(firstValue: 0, length: 3) | |
range.firstValue = 6 | |
let constantRange = range // constant value, can't change properties | |
// lazy stored properties | |
class DataImporter { | |
var fileName = "data.txt" | |
} | |
class DataManager { | |
@lazy var importer = DataImporter() | |
var data = String[]() | |
} | |
let manager = DataManager() | |
manager.data += "data" | |
manager.data += "more data" | |
manager.importer.fileName // lazily instantiated here | |
// computed properties | |
struct Point { | |
var x = 0.0, y = 0.0 | |
} | |
struct Size { | |
var width = 0.0, height = 0.0 | |
} | |
struct Rect { | |
var origin = Point() | |
var size = Size() | |
var center: Point { | |
get { | |
let centerX = origin.x + (size.width / 2) | |
let centerY = origin.y + (size.height / 2) | |
return Point(x: centerX, y: centerY) | |
} | |
set(newCenter) { | |
origin.x = newCenter.x - (size.width / 2) | |
origin.y = newCenter.y - (size.height / 2) | |
} | |
// shorthand: | |
// set { | |
// origin.x = newValue.x - (size.width / 2) | |
// origin.y = newValue.y - (size.height / 2) | |
// } | |
} | |
} | |
var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0)) | |
square.origin.x | |
square.origin.y | |
square.center = Point(x: 15.0, y: 15.0) | |
square.origin.x | |
square.origin.y | |
// read-only computed properties | |
struct Cuboid { | |
var width = 0.0, height = 0.0, depth = 0.0 | |
var volume: Double { | |
return width * height * depth | |
} | |
} | |
let cube = Cuboid(width: 4.0, height: 5.0, depth: 2.0) | |
cube.volume // 40.0 | |
// property observers | |
class StepCounter { | |
var totalSteps: Int = 0 { | |
willSet(newTotalSteps) { | |
string = "About to set totalSteps to \(newTotalSteps)" | |
} | |
didSet { | |
string = "totalSteps is now \(totalSteps)" | |
} | |
} | |
} | |
let stepCounter = StepCounter() | |
stepCounter.totalSteps = 200 | |
// => About to set totalSteps to 200 | |
// => totalSteps is now 200 | |
// type properties: (like class variables) | |
struct SomeStructure { | |
// value types can have stored and computed type properties: | |
static var storedTypeProperty = "Some value." | |
static var computedTypeProperty: Int { | |
return 3 + 5 | |
} | |
} | |
SomeStructure.storedTypeProperty // "Some value" | |
SomeStructure.computedTypeProperty // 8 | |
class SomeClass { | |
// classes can only have computed type properties | |
class var computedTypeProperty: Int { | |
return 3 + 5 | |
} | |
} | |
SomeClass.computedTypeProperty // 8 | |
// type properties example | |
struct AudioChannel { | |
static let thresholdLevel = 10 | |
static var maxInputLevelForAllChannels = 0 | |
var currentLevel: Int = 0 { | |
didSet { | |
if currentLevel > AudioChannel.thresholdLevel { | |
// cap the new audio level to the threshold level | |
currentLevel = AudioChannel.thresholdLevel | |
} | |
if currentLevel > AudioChannel.maxInputLevelForAllChannels { | |
// store this as the new overall maximum input level | |
AudioChannel.maxInputLevelForAllChannels = currentLevel | |
} | |
} | |
} | |
} | |
var leftChannel = AudioChannel() | |
var rightChannel = AudioChannel() | |
leftChannel.currentLevel = 7 | |
AudioChannel.maxInputLevelForAllChannels // 7 | |
rightChannel.currentLevel = 11 | |
AudioChannel.maxInputLevelForAllChannels // 10 | |
// subscripts | |
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4] | |
numberOfLegs["bird"] = 2 | |
struct TimesTable { | |
let multiplier: Int | |
// read-only subscript | |
subscript(index: Int) -> Int { | |
return multiplier * index | |
} | |
} | |
let threeTimesTable = TimesTable(multiplier: 3) | |
int = threeTimesTable[6] // 18 | |
// INHERITANCE | |
class Vehicle { | |
var numberOfWheels: Int | |
var maxPassengers: Int | |
init() { | |
numberOfWheels = 0 | |
maxPassengers = 1 | |
} | |
func description() -> String { | |
return "\(numberOfWheels) wheels" | |
} | |
} | |
class Car: Vehicle { | |
var speed: Double = 0.0 | |
init() { | |
super.init() | |
maxPassengers = 5 | |
numberOfWheels = 4 | |
} | |
override func description() -> String { | |
return super.description() + "; " | |
+ "traveling at \(speed) mph" | |
} | |
} | |
let car = Car() | |
string = car.description() | |
// overriding property getters and setters | |
class SlowCar: Car { | |
override var speed: Double { | |
get { | |
return super.speed | |
} | |
set { | |
super.speed = min(newValue, 40.0) | |
} | |
} | |
} | |
let slowcar = SlowCar() | |
slowcar.speed = 60.0 | |
string = slowcar.description() | |
// overriding property observers | |
class AutomaticCar: Car { | |
var gear = 1 | |
override var speed: Double { | |
didSet { | |
gear = Int(speed / 10.0) + 1 | |
} | |
} | |
override func description() -> String { | |
return super.description() + " in gear \(gear)" | |
} | |
} | |
let automatic = AutomaticCar() | |
automatic.speed = 35.0 | |
string = automatic.description() | |
// INITIALIZERS | |
// default initializer | |
class ShoppingListItem { | |
var name: String? | |
var quantity = 1 | |
var purchased = false | |
} | |
var item = ShoppingListItem() | |
int = item.quantity | |
// multiple initializers | |
struct Celsius { | |
var temperatureInCelsius: Double = 0.0 | |
init(fromFahrenheit fahrenheit: Double) { | |
temperatureInCelsius = (fahrenheit - 32.0) / 1.8 | |
} | |
init(fromKelvin kelvin: Double) { | |
temperatureInCelsius = kelvin - 273.15 | |
} | |
} | |
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0) | |
let freezingPointOfWater = Celsius(fromKelvin: 273.15) | |
// initializer external parameter names | |
struct Color { | |
let red = 0.0, green = 0.0, blue = 0.0 | |
// parameters are automatically internal and external | |
init(red: Double, green: Double, blue: Double) { | |
self.red = red | |
self.green = green | |
self.blue = blue | |
} | |
} | |
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0) | |
// memberwise initializers for structs | |
struct Sizey { | |
var width = 0.0, height = 0.0 | |
} | |
let twoByTwo = Sizey(width: 2.0, height: 2.0) | |
// initializer delegation | |
struct Recty { | |
var origin = Point() | |
var size = Size() | |
init() {} | |
init(origin: Point, size: Size) { | |
self.origin = origin | |
self.size = size | |
} | |
init(center: Point, size: Size) { | |
let originX = center.x - (size.width / 2) | |
let originY = center.y - (size.height / 2) | |
self.init(origin: Point(x: originX, y: originY), size: size) | |
} | |
} | |
let basicRect = Recty() | |
let originRect = Recty(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0)) | |
let centerRect = Recty(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0)) | |
// designated and convenience initializers | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment