Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift: An Introduction to the Language

Kris Arnold
October 01, 2014

Swift: An Introduction to the Language

The talk introduces Swift to someone who already understands programming but is not familiar with Objective-C. High-level concepts are presented and backed up with simple code samples. Concepts which many engineers might have never encountered, such as protocols and generics, are discussed and illustrated with examples. The talk focuses only on the Swift language and does not discuss writing apps for iOS or OS X.

Watch a video of the talk at https://www.youtube.com/watch?v=YyJshuAHl1g

Kris Arnold

October 01, 2014
Tweet

More Decks by Kris Arnold

Other Decks in Technology

Transcript

  1. Disclaimer The only people with more than a few months

    experience with Swift work at Apple
  2. Topics Language Design Principles Why a new language? Variables and

    Data Structures Flow Control Functions and Closures Classes and Protocols Structs and Enums Generics What Else? What's Missing? What's Next?
  3. var cities = ["New York", "Berlin"] cities[0] // "New York"

    cities.append("San Francisco") cities.insert("Denver", atIndex: 0)
  4. var cities = ["New York", "Berlin"] cities[0] // "New York"

    cities.append("San Francisco") cities.insert("Denver", atIndex: 0) cities.count // 4
  5. var populations = [String: Int]() populations = ["New York": 8_300_000,

    "Berlin": 3_500_000] populations["Denver"] = 600_000 populations["San Francisco"] = 800_000
  6. var populations = [String: Int]() populations = ["New York": 8_300_000,

    "Berlin": 3_500_000] populations["Denver"] = 600_000 populations["San Francisco"] = 800_000 populations["New York"] // 8_300_000
  7. if … then … else for … in loops C-style

    for loops While loops Do-while loops
  8. var nickname: String? … if let moniker = nickname {

    println("Hello \(moniker)") } else { println("Hello friend") }
  9. func sayHello(name: String) -> () { println "Hello \(name)" }

    sayHello("Lattner") // prints "Hello Lattner"
  10. func sayHello(var name: String) -> (String) { name += "!"

    return "Hello \(name)" } var person = "Lattner" sayHello(person)
  11. func sayHello( name: String) -> (String) { name += "!"

    return "Hello \(name)" } var person = "Lattner" sayHello( person) println("Updated to \(person)") // "Updated to Lattner!"
  12. func sayHello(inout name: String) -> (String) { name += "!"

    return "Hello \(name)" } var person = "Lattner" sayHello(&person) println("Updated to \(person)") // "Updated to Lattner!"
  13. var items = [100, 2, 75, 31, 99] items.sort //

    items is now [2, 31, 75, 99, 100]
  14. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) } items.sort(sorter)
  15. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) -> Bool in } items.sort(sorter)
  16. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) -> Bool in } items.sort(sorter)
  17. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) -> Bool in return num1 < num2 } items.sort(sorter)
  18. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) -> Bool in return num1 < num2 } items.sort(sorter)
  19. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) -> Bool in num1 < num2 } items.sort(sorter)
  20. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1: Int, num2: Int) in num1 < num2 } items.sort(sorter)
  21. var items = [100, 2, 75, 31, 99] let sorter

    = { (num1, num2) in num1 < num2 } items.sort(sorter)
  22. let list = [1, 2, 3, 4, 5, 6, 7,

    8, 9, 10] let evens = list.filter { $0 % 2 == 0 }
  23. let list = [1, 2, 3, 4, 5, 6, 7,

    8, 9, 10] let evens = list.filter { $0 % 2 == 0 } let tenX = list.map { $0 * 10 }
  24. let list = [1, 2, 3, 4, 5, 6, 7,

    8, 9, 10] let evens = list.filter { $0 % 2 == 0 } let tenX = list.map { $0 * 10 } let sum = list.reduce(0) { $0 + $1 }
  25. func makeMultiplier(number: Int) -> Int -> (Int) { let multiplier

    = { (given: Int) -> Int in return number * given } }
  26. func makeMultiplier(number: Int) -> Int -> (Int) { let multiplier

    = { (given: Int) -> Int in return number * given } return multiplier }
  27. func makeMultiplier(number: Int) -> Int -> (Int) { let multiplier

    = { (given: Int) -> Int in return number * given } return multiplier } let timesTwenty = makeMultiplier(20)
  28. func makeMultiplier(number: Int) -> Int -> (Int) { let multiplier

    = { (given: Int) -> Int in return number * given } return multiplier } let timesTwenty = makeMultiplier(20) timesTwenty(3) // output == 60
  29. func makeMultiplier(number: Int) -> Int -> (Int) { let multiplier

    = { (given: Int) -> Int in return number * given } return multiplier } let timesTwenty = makeMultiplier(20) timesTwenty(3) // output == 60 let timesFifty = makeMultiplier(50) timesFifty(3) // output == 150
  30. class Image { var mediaId = 0 var description =

    "My awesome image" } var myImage = Image() myImage.mediaId = 200_000
  31. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } }
  32. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId } }
  33. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } }
  34. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } func approveImage() -> () { println("Approving…") } }
  35. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } func approveImage() -> () { println("Approving…") } }
  36. var myImage = Image( mediaId: 200_000, description: "Testing" ) println("the

    description for \(myImage.mediaId) is \(myImage.description)")
  37. var myImage = image( mediaId: 200_000, description: "Testing" ) println("the

    description for \(myImage.mediaId) is \(myImage.description)") myImage.approveImage()
  38. var myImage = image( mediaId: 200_000, description: "Testing" ) println("the

    description for \(myImage.mediaId) is \(myImage.description)") myImage.approveImage() myImage.description = betterDescription
  39. class Image { var mediaId :Int var description :String {

    didSet { println("Changed desc to \(description)") updateAuditTrail(mediaId, description) } } //… }
  40. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } }
  41. class Image { let mediaId :Int let description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } }
  42. class Image { let mediaId :Int let description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } } //… image.description = betterDescription // error!
  43. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } }
  44. class Image { var mediaId :Int var description :String var

    height :Int var width :Int var aspectRatio :Float … }
  45. class Image { var mediaId :Int var description :String var

    height :Int var width :Int var aspectRatio :Float { return Float(height) / Float(width) } … }
  46. class Image { var mediaId :Int var description :String var

    height :Int var width :Int var aspectRatio :Float { return Float(height) / Float(width) } … }
  47. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description } }
  48. class Image: Media { var mediaId :Int var description :String

    init(mediaId: Int, description: String) { self.mediaId = mediaId self.description = description } }
  49. class Image: Media { var mediaId :Int var description :String

    init(mediaId: Int, description: String) { super.init() // error! self.mediaId = mediaId self.description = description } }
  50. class Image: Media { var mediaId :Int var description :String

    init(mediaId: Int, description: String) { self.mediaId = mediaId self.description = description super.init() // correct! } }
  51. class Image: Media { var mediaId :Int var description :String

    init(mediaId: Int, description: String) { self.mediaId = mediaId self.description = description super.init() // correct! } func upload() -> () { println("Uploading…") } }
  52. class Image: Media { var mediaId :Int var description :String

    init(mediaId: Int, description: String) { self.mediaId = mediaId self.description = description super.init() // correct! } override func upload() -> () { println("Uploading…") } }
  53. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description super.init() // correct! } func upload() -> () { println("Uploading…") } }
  54. class Image { var mediaId :Int var description :String init(mediaId:

    Int, description: String) { self.mediaId = mediaId self.description = description super.init() // correct! } final func upload() -> () { println("Uploading…") } }
  55. final class Image { var mediaId :Int var description :String

    init(mediaId: Int, description: String) { self.mediaId = mediaId self.description = description super.init() // correct! } func upload() -> () { println("Uploading…") } }
  56. class Image { var mediaId :Int var description :String //…

    func upload() -> () { println("Uploading…") } }
  57. class Image { var mediaId :Int private var description :String

    //… private func upload() -> () { println("Uploading…") } }
  58. private class Image { var mediaId :Int private var description

    :String //… private func upload() -> () { println("Uploading…") } }
  59. internal class Image { var mediaId :Int internal var description

    :String //… private func upload() -> () { println("Uploading…") } }
  60. class Uploader { func upload(uploadee: Media) { uploadee.uploadInProgress() doHTTPUpload(source: uploadee.filePath,

    destination: uploadee.fileName) uploadee.uploadComplete() } func doHTTPUpload(#source: String, #destination: String) -> () { // hand-waving… } }
  61. class Media { var mediaId: Int = 200_000 var filePath:

    String = "/tmp/media.jpg" var fileType: String = "jpg" var fileName: String { return String(mediaId) + "." + fileType } func uploadInProgress() -> () { // do stuff } func uploadComplete() -> () { // do stuff } }
  62. class Media { var mediaId: Int = 200_000 var filePath:

    String = "/tmp/media.jpg" var fileType: String = "jpg" var fileName: String { return String(mediaId) + "." + fileType } func uploadInProgress() -> () { // do stuff } func uploadComplete() -> () { // do stuff } }
  63. class Uploader { func upload(uploadee: Media) { uploadee.uploadInProgress() doHTTPUpload(source: uploadee.filePath,

    destination: uploadee.fileName) uploadee.uploadComplete() } func doHTTPUpload(#source: String, #destination: String) -> () { // hand-waving… } }
  64. class Uploader { func upload(uploadee: Media) { uploadee.uploadInProgress() doHTTPUpload(source: uploadee.filePath,

    destination: uploadee.fileName) uploadee.uploadComplete() } func doHTTPUpload(#source: String, #destination: String) -> () { // hand-waving… } }
  65. protocol Uploadable { var filePath: String { get } var

    fileName: String { get } func uploadInProgress() -> () func uploadComplete() -> () }
  66. class Uploader { func upload(uploadee: Media) { uploadee.uploadInProgress() doHTTPUpload(source: uploadee.filePath,

    destination: uploadee.fileName) uploadee.uploadComplete() } func doHTTPUpload(#source: String, #destination: String) -> () { // hand-waving… } }
  67. class Uploader { func upload(uploadee: Uploadable) { uploadee.uploadInProgress() doHTTPUpload(source: uploadee.filePath,

    destination: uploadee.fileName) uploadee.uploadComplete() } func doHTTPUpload(#source: String, #destination: String) -> () { // hand-waving… } }
  68. class Media { var mediaId: Int = 200_000 var filePath:

    String = "/tmp/media.jpg" var fileType: String = "jpg" var fileName: String { return String(mediaId) + "." + fileType } func uploadInProgress() -> () { // do stuff } func uploadComplete() -> () { // do stuff } }
  69. class Media: Uploadable { var mediaId: Int = 200_000 var

    filePath: String = "/tmp/media.jpg" var fileType: String = "jpg" var fileName: String { return String(mediaId) + "." + fileType } func uploadInProgress() -> () { // do stuff } func uploadComplete() -> () { // do stuff } }
  70. struct CGPoint { CGFloat x; CGFloat y; }; struct CGSize

    { CGFloat width; CGFloat height; };
  71. struct CGPoint { CGFloat x; CGFloat y; }; struct CGSize

    { CGFloat width; CGFloat height; }; struct CGRect { CGPoint origin; CGSize size; };
  72. struct CGPoint { CGFloat x; CGFloat y; }; struct CGSize

    { CGFloat width; CGFloat height; }; struct CGRect { CGPoint origin; CGSize size; }; 16.67
  73. CGPointMake CGRectMake CGSizeMake CGRectDivide CGRectInset CGRectIntegral CGRectIntersection CGRectOffset CGRectUnion CGPointEqualToPoint

    CGSizeEqualToSize CGRectEqualToRect CGRectIntersectsRect CGRectContainsPoint CGRectContainsRect CGRectGetMinX CGRectGetMinY CGRectGetMidX CGRectGetMidY CGRectGetMaxX CGRectGetMaxY CGRectGetHeight CGRectGetWidth CGRectIsEmpty CGRectIsNull CGRectIsInfinite
  74. struct Image { var mediaId: Int var description: String func

    upload() -> () { println("Uploading image \(self.mediaId)") } }
  75. struct Image { var mediaId: Int var description: String func

    upload() -> () { println("Uploading image \(self.mediaId)") } } var myImage = Image(mediaId: 200_000, description: "test")
  76. struct Image { var mediaId: Int var description: String func

    upload() -> () { println("Uploading image \(self.mediaId)") } } var myImage = Image(mediaId: 200_000, description: "test") myImage.upload()
  77. struct Image { var mediaId: Int var description: String func

    upload() -> () { println("Uploading image \(self.mediaId)") } func bang() -> () { self.description.extend("!") } }
  78. struct Image { var mediaId: Int var description: String func

    upload() -> () { println("Uploading image \(self.mediaId)") } mutating func bang() -> () { self.description.extend("!") } }
  79. var imageStruct = imageStr(mediaId: 200_000, description: "Flowers") var newImageStruct =

    imageStruct imageStruct.description = "Kittens" println(\(newImaegStruct.description)) // prints "Flowers"
  80. var imageStruct = imageStr(mediaId: 200_000, description: "Flowers") var newImageStruct =

    imageStruct imageStruct.description = "Kittens" println(\(newImaegStruct.description)) // prints "Flowers" var imageObject = imageObj(mediaId: 200_000, description: "Flowers") var newImageObject = imageObject
  81. var imageStruct = imageStr(mediaId: 200_000, description: "Flowers") var newImageStruct =

    imageStruct imageStruct.description = "Kittens" println(\(newImaegStruct.description)) // prints "Flowers" var imageObject = imageObj(mediaId: 200_000, description: "Flowers") var newImageObject = imageObject imageObject.description = "Kittens"
  82. var imageStruct = imageStr(mediaId: 200_000, description: "Flowers") var newImageStruct =

    imageStruct imageStruct.description = "Kittens" println(\(newImaegStruct.description)) // prints "Flowers" var imageObject = imageObj(mediaId: 200_000, description: "Flowers") var newImageObject = imageObject imageObject.description = "Kittens" println(\(newImageObject.description)) // prints "Kittens"
  83. struct Image { var mediaId: Int var description: String var

    orientation: Orientation } var myImage = Image( mediaId: 200_000, description: "Test", orientation: Orientation.Landscape )
  84. struct Image { var mediaId: Int var description: String var

    orientation: Orientation } var myImage = Image( mediaId: 200_000, description: "Test", orientation: Orientation.Landscape )
  85. struct Image { var mediaId: Int var description: String var

    orientation: Orientation } var myImage = Image( mediaId: 200_000, description: "Test", orientation: .Landscape )
  86. enum Orientation { case Portrait case Landscape case Square func

    describe () -> () { switch self { case .Portrait: println("Portrait orientation") case .Landscape: println("Landscape orientation") case .Square: println("What is this, Instagram?") } } }
  87. struct Image { enum Orientation { case Portrait case Landscape

    case Square } var mediaId: Int var description: String var orientation: Orientation }
  88. struct Lightbox { var items: [Image] mutating func addItem(item: Image)

    -> () { self.items.append(item) } mutating func merge(other: Lightbox) -> () { for item in other.items { self.addItem(item) } } }
  89. struct Lightbox { var items: [Image] mutating func addItem(item: Image)

    -> () { self.items.append(item) } mutating func merge(other: Lightbox) -> () { for item in other.items { self.addItem(item) } } }
  90. struct Lightbox { var items: [Image] mutating func addItem(item: Image)

    -> () { self.items.append(item) } mutating func merge(other: Lightbox) -> () { for item in other.items { self.addItem(item) } } }
  91. struct Clipbox { var items: [Video] mutating func addItem(item: Video)

    -> () { self.items.append(item) } mutating func merge(other: Clipbox) -> () { for item in other.items { self.addItem(item) } } }
  92. struct Clipbox { var items: [Video] mutating func addItem(item: Video)

    -> () { self.items.append(item) } mutating func merge(other: Clipbox) -> () { for item in other.items { self.addItem(item) } } }
  93. struct Mediabox<T> { var items: [T] = [] mutating func

    addItem(item: T) -> () { self.items.append(item) } mutating func merge(other: Mediabox<T>) -> () { for item in other.items { self.addItem(item) } } }
  94. var myLightbox = Mediabox<Image>() myLightbox.addItem(flowerImage) myLightbox.addItem(kittenImage) var myClipbox = Mediabox<Video>()

    myClipbox.addItem(surferVid) myClipbox.addItem(skierVid) myLightbox.addItem(surferVid) //error! myClipbox.merge(other: myLightbox) //error!
  95. @autoclosure automatic reference counting avoiding circular references with the weak

    keyword variadic parameters closed vs. open ranges associated and raw values for Enums where clauses in generics the Swift standard library operator overloading sequences and generators typealias type casting AnyObject calling Objective-C from Swift calling Swift from Objective-C