a swift introduction to swift
Post on 27-Aug-2014
36.999 Views
Preview:
DESCRIPTION
TRANSCRIPT
A swift introduction to
Giordano ScalzoClosure Busker
with different reactions
but also
From
To
What does Swift look like?
SHOW ME THE CODE!!!!!
let individualScores = [75, 43, 103, 87, 12] var teamScore = 0 for score in individualScores { if score > 50 { teamScore += 3 } else { teamScore += 1 } } teamScore
;
;
var optionalName: String? = "John Appleseed" var greeting = "Hello!" !if optionalName { greeting = "Hello, \(optionalName!)" }
Optional
var optionalName: String? = "John Appleseed" var greeting = "Hello!" !if let name = optionalName { greeting = "Hello, \(name)" }
Optional
if let upper = john.residence?.address?.buildingIdentifier()?.uppercaseString { println("John's uppercase building identifier is \(upper).") } else { println("I can't find John's address") }
Optional Chaining
Playground
Switch on steroids
let vegetable = "red pepper" switch vegetable { case "celery": let vegetableComment = "Add raisins." case "cucumber", "watercress": let vegetableComment = "sandwich." case let x where x.hasSuffix("pepper"): let vegetableComment = "Is it a spicy \(x)?" default: let vegetableComment = "Soup." }
let somePoint = (1, 1) switch somePoint { case (0, 0): println("(0, 0) is at the origin") case (_, 0): println("(\(somePoint.0), 0) is on the x-axis") case (0, _): println("(0, \(somePoint.1)) is on the y-axis") case (-2...2, -2...2): println("(\(somePoint.0), \(somePoint.1)) is inside the box") default: println("(\(somePoint.0), \(somePoint.1)) is outside of the box") }
Functions and closures
func greet(name: String, #day: String) -> String { return "Hello \(name), today is \(day)." } greet("Bob", day: "Wednesday")
Named Parameters
func greet(name: String, day: String) -> String { return "Hello \(name), today is \(day)." } greet("Bob", "Wednesday")
Named Parameters Optional
Multiple result using tuples
func getGasPrices()->(Double, Double, Double) { return (3.59, 3.69, 3.79) } let (min, avg, max) = getGasPrices() println("min is \(min), max is \(max)")
Multiple result using tuples
func getGasPrices()->(Double, Double, Double) { return (3.59, 3.69, 3.79) } let gasPrices = getGasPrices() println("min is \(gasPrices.0), max is \(gasPrices.2)")
Functions are first class type
func makeIncrementer() -> (Int -> Int) { func addOne(number: Int) -> Int { return 1 + number } return addOne } var increment = makeIncrementer() increment(7)
A function can be a return value
or a function parameter
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool { for item in list { if condition(item) { return true } } return false } func lessThanTen(number: Int) -> Bool { return number < 10 } var numbers = [20, 19, 7, 12] hasAnyMatches(numbers, lessThanTen)
anonymous function
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool { for item in list { if condition(item) { return true } } return false } func lessThanTen(number: Int) -> Bool { return number < 10 } var numbers = [20, 19, 7, 12] hasAnyMatches(numbers, { num in num < 10})
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool { for item in list { if condition(item) { return true } } return false } func lessThanTen(number: Int) -> Bool { return number < 10 } var numbers = [20, 19, 7, 12] hasAnyMatches(numbers) { num in num < 10}
anonymous function
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool { for item in list { if condition(item) { return true } } return false } func lessThanTen(number: Int) -> Bool { return number < 10 } var numbers = [20, 19, 7, 12] hasAnyMatches(numbers) { $0 < 10}
anonymous function
Where are the classes?
class NamedShape { var numberOfSides: Int = 0 var name: String init(name: String) { self.name = name } func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } }
class Square: NamedShape { var sideLength: Double init(sideLength: Double, name: String) { self.sideLength = sideLength super.init(name: name) numberOfSides = 4 } func area() -> Double { return sideLength * sideLength } override func simpleDescription() -> String { return "A square with sides of length \(sideLength)." } } !let test = Square(sideLength: 5.2, name: "my test square") test.area() test.simpleDescription()
class Square: NamedShape { var sideLength: Double init(sideLength len: Double, name: String) { self.sideLength = len super.init(name: name) numberOfSides = 4 } func area() -> Double { return sideLength * sideLength } override func simpleDescription() -> String { return "A square with sides of length \(sideLength)." } } !let test = Square(sideLength: 5.2, name: "my test square") test.area() test.simpleDescription()
class Square: NamedShape { var sideLength: Double init(_ sideLength: Double, _ name: String) { self.sideLength = sideLength super.init(name: name) numberOfSides = 4 } func area() -> Double { return sideLength * sideLength } override func simpleDescription() -> String { return "A square with sides of length \(sideLength)." } } !let test = Square(5.2, "my test square") test.area() test.simpleDescription()
class EquilateralTriangle: NamedShape { var sideLength: Double = 0.0 ... var perimeter: Double { get { return 3.0 * sideLength } set { sideLength = newValue / 3.0 } } ... }
calculated properties
class TriangleAndSquare { var triangle: EquilateralTriangle { willSet { square.sideLength = newValue.sideLength } } var square: Square { willSet { triangle.sideLength = newValue.sideLength } } }
observable properties
struct Card { var rank: Rank var suit: Suit func simpleDescription() -> String { return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" } } let threeOfSpades = Card(rank: Card.Three, suit: Card.Spades) let threeOfSpadesDescription = threeOfSpades.simpleDescription()
Structs
struct Card { var rank: Rank var suit: Suit func simpleDescription() -> String { return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" } } let threeOfSpades = Card(rank: .Three, suit: .Spades) let threeOfSpadesDescription = threeOfSpades.simpleDescription()
Structs
like classes, but passed by value...in a smarter way
classes are always passed by reference
structs are passed by reference, but automatically copied when mutated
Struct are used as ValueTypes, data components manipulated by classes
https://www.destroyallsoftware.com/talks/boundaries
enum Rank: Int { case Ace = 1 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King func simpleDescription() -> String { switch self { case .Ace: return "ace" case .Jack: return "jack" case .Queen: return "queen" case .King: return "king" default: return String(self.toRaw()) } } }
Enumerations on steroids
enum ServerResponse { case Result(String, String) case Error(String) }
Enumerations with a value associated
Enumerations with a value associated
let success = ServerResponse.Result("6:00 am", "8:09 pm") let failure = ServerResponse.Error("Out of cheese.")
Pattern matching to extract associated values
switch result { case let .Result(sunrise, sunset): let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)." case let .Error(error): let serverResponse = "Failure... \(error)" }
protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() }
Protocols... like Interface in Java or... protocols in Objective-C
extension Int: ExampleProtocol { var simpleDescription: String { return "The number \(self)" } mutating func adjust() { self += 42 } } 7.simpleDescription
extensions... like categories in Objective-C
Generics
func repeatString(item: String, times: Int) -> String[] { var result = String[]() for i in 0..times { result += item } return result } repeatString("knock", 4)
!func repeatInt(item: Int, times: Int) -> Int[] { var result = Int[]() for i in 0..times { result += item } return result } repeatInt(42, 4)
func repeat<T>(item: T, times: Int) -> T[] { var result = T[]() for i in 0..times { result += item } return result } repeat("knock", 4) repeat(42, 3)
Operator overload@infix func +(t1: Int, t2: Int) -> Int{ return 3 } !@prefix func +(t1: Int) -> Int{ return 5 } !var a = 20 var b = 111 !a + b // 3 a - +b // 15
But the most important feature, the only one that you need to learn is...
Emoji!!!
For me (imvho) the most useful new features are enumerations and pattern
matching
Unit Test support
XCTest
class RpnCalculatorKataTests: XCTestCase { override func setUp() { super.setUp() } override func tearDown() { super.tearDown() } func testExample() { XCTAssert(true, "Pass") } func testPerformanceExample() { self.measureBlock() { } } }
Quickclass PersonSpec: QuickSpec { override class func exampleGroups() { describe("Person") { var person: Person? beforeEach { person = Person() } describe("greeting") { context("when the person is unhappy") { beforeEach { person!.isHappy = false } it("is lukewarm") { expect(person!.greeting).to.equal("Oh, hi.") expect(person!.greeting).notTo.equal("Hello!") } } } } } }
And now...
Let's code
a Rpn Calculator
enum Key : String { case One = "1" //... case Enter = "enter" case Plus = "+" case Minus = "-" } !protocol RpnCalculator { var display : String[] { get } func press(key: Key) }
https://github.com/gscalzo/RpnCalculatorKata
top related