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

A Linguagem Swift

A Linguagem Swift

Jean Pimentel

December 17, 2014
Tweet

More Decks by Jean Pimentel

Other Decks in Technology

Transcript

  1. Swift
    Swift = Objective-C
    - C

    View full-size slide

  2. Swift
    Swift = Objective-C
    - C
    sem ponteiros

    View full-size slide

  3. Swift
    Influências:
    Objective-C, Rust, Ruby, Python, C#,
    Haskell
    ...

    View full-size slide

  4. Swift
    Swift = Objective-Haskell

    View full-size slide

  5. Criador
    Chris Lattner
    Criador do ecossistema
    LLVM
    Diretor do departamento
    Developer Tools
    Julho
    2010
    Julho
    2013

    Setembro
    2014
    1.0

    View full-size slide

  6. O que muda?
    ~80% da complexidade no desenvolvimento
    para iOS/OSX está no
    Cocoa

    View full-size slide

  7. Legibilidade

    sem [ ] para métodos

    sem ;

    if obriga uso de
    { }
    – If ... { ... }

    condicionais explícitas
    – if (meuObjeto)
    vs if meuObjeto != nil { … }

    View full-size slide

  8. Tipagem

    Forte

    Estática

    Inferida

    Tipo Opcional
    T?
    enum Optional { case None, Some(T) }

    View full-size slide

  9. Tipagem
    var k = 1024 // 1,024
    var M = 1_048_576 // 1,048,576
    var G: Int
    G = k * M // 1,073,741,824

    View full-size slide

  10. Tipagem
    var olá = "Olá mundo!"
    olá = 3 // ERROR
    var a = [
    "alpha"
    , "beta"
    , "gamma"
    ] // ["alpha", "beta", "gamma"]
    var b: [
    String
    ] = [
    "um"
    , "dois"
    , "três"
    ] // ["um", "dois", "três"]
    var c: [
    String
    ]
    c = [
    "alpha"
    ] // ["alpha"]
    c += [
    "beta"
    ] // ["alpha", "beta"]
    var g = [
    "pi"
    : 3.14
    , "e": 2.71
    ] // ["pi": 3.14, "e": 2.71]
    var ascii: [
    String
    : Int] = [
    "A": 65, "B": 66] // ["A": 65, "B": 66]

    View full-size slide

  11. Tipagem
    var a: Int // nil
    a = 1 // 1
    a = nil // ERROR
    var b: Int? // nil
    b = 5 // {Some 5}
    b = nil // nil

    View full-size slide

  12. Tipagem
    var b: Int? // nil
    b = 4 // {Some 4}
    if b != nil {
    println
    ("B tem valor
    \(b)") // "B tem valor Optional(4)"
    println
    ("B tem valor
    \(b!)") // "B tem valor 4"
    }
    if let tmp = b {
    println
    ("B tem valor
    \(tmp)
    ") // "B tem valor 4"
    }

    View full-size slide

  13. Mutabilidade

    NSMutableArray vs NSArray

    NSMutableDictionary vs NSDictionary

    NSMutableString vs NSString

    View full-size slide

  14. Mutabilidade

    NSMutableArray vs NSArray

    NSMutableDictionary vs NSDictionary

    NSMutableString vs NSString
    var vs let

    View full-size slide

  15. Mutabilidade
    var str = "Olá" // "Olá"
    str += ", mundo!" // "Olá, mundo!"
    let hello = "Hello" // "Hello"
    hello = "Hello, world!" // ERROR

    View full-size slide

  16. Tuplas
    let codes = [(
    401, "Unauthorized"
    ), (
    403, "Forbidden"
    ), (
    404, "Not Found"
    )]
    for code in codes {
    println
    (code.
    0, code.
    1)
    }
    let notFound =
    codes
    .last
    !
    println
    ("Code \(notFound
    .0) - \(notFound
    .1)") "Code 404 - Not Found"
    let (code, message) =
    codes
    .last
    !
    println
    ("Code \(code
    ) - \(message
    )") "Code 404 - Not Found"
    let (_, error) =
    codes
    .last
    !
    println
    ("Error: \(error
    )") "Error: Not Found"

    View full-size slide

  17. sasa
    Switch/Case

    View full-size slide

  18. Switch, Case

    sem break

    fallthrough explícito

    View full-size slide

  19. Switch, Case
    switch (error.code) {
    case kErrorFailConnection:
    NSLog(@”sem conexão”);
    break;
    case kErrorUnexpected:
    case kErrorServerError:
    case kErrorUnexpectedResponse:
    NSLog(@”erro no serviço”);
    break;
    default:
    NSLog(@”erro não esperado”);
    break;
    }

    View full-size slide

  20. Switch, Case
    switch (error.code) {
    case kErrorFailConnection:
    NSLog(@”sem conexão”);
    break;
    case kErrorUnexpected:
    case kErrorServerError:
    case kErrorUnexpectedResponse:
    NSLog(@”erro no serviço”);
    break;
    default:
    NSLog(@”erro não esperado”);
    break;
    }
    switch (error.code) {
    case kErrorFailConnection:
    println(”sem conexão”)
    case kErrorUnexpected:
    fallthrough
    case kErrorServerError:
    fallthrough
    case kErrorUnexpectedResponse:
    println(”erro no serviço”)
    default:
    println(”erro não esperado”)
    }

    View full-size slide

  21. Switch, Case
    switch quantidade {
    case 0:
    println("nenhum comentário")
    case 1...9:
    println("poucos comentários")
    case 10...99:
    println("dezenas de comentários")
    case 100...999:
    println("centenas de comentários")
    case 1000...999_999:
    println("milhares de comentários")
    default:
    println("vish")
    }

    View full-size slide

  22. Switch, Case
    let points = [(2, 0), (0, 3), (1, 1), (0, 0), (4, 3)]
    for point in points {
    switch point {
    case (0, 0):
    println("Origem")
    case (_, 0):
    println("Eixo X")
    case (0, _):
    println("Eixo Y")
    case (let x, let y) where x == y:
    println("X = Y")
    default:
    println("Nada especial")
    }
    }

    View full-size slide

  23. sasa
    Funções

    View full-size slide

  24. Funções
    func hello(name:
    String
    ) {
    println
    ("Hello, \(name)
    !")
    }
    hello
    ("Bob"
    ) // "Hello, Bob!"
    func hello(name:
    String
    ) -> String {
    return "Hello, \(name)
    !"
    }
    let a = hello(
    "Bob"
    ) // "Hello, Bob!"
    func hello(_ name:
    String = "World"
    ) -> String {
    return "Hello, \(name)
    !"
    }
    let a = hello
    ("Bob"
    ) // "Hello, Bob!"
    let b = hello
    () // "Hello, World!"

    View full-size slide

  25. Funções
    func div(dividend:
    Int, divisor:
    Int) -> Int? {
    if divisor ==
    0 {
    return nil
    }
    return dividend / divisor
    }
    let a = div(5, 2) // {Some 2}
    let b = div(2, 0) // nil
    func divAndMod(dividend:
    Int, divisor:
    Int) -> (
    Int, Int)? {
    if divisor ==
    0 {
    return nil
    }
    return (dividend / divisor, dividend % divisor)
    }
    let c = divAndMod
    (5, 2) // {(.0 2, .1 1)}
    let d = divAndMod
    (2, 0) // nil

    View full-size slide

  26. func cpf(cpf: String
    ) -> Bool { return ... }
    func cnpj(cnpj:
    String
    ) -> Bool { return ... }
    func validate(input:
    String
    , rule: (
    String -> Bool
    )) -> Bool {
    return rule(input)
    }
    let input = "012.345.678-90"
    let isValid =
    validate
    (input
    , countElements
    (input
    ) == 14 ? cpf : cnpj
    )
    Funções

    objetos de primeira classe

    View full-size slide

  27. func cpf(cpf: String
    ) -> Bool { return ... }
    func cnpj(cnpj:
    String
    ) -> Bool { return ... }
    func validate(
    var input: String
    , rule: (
    String -> Bool
    )) -> Bool {
    input = removeNonDigits
    (input
    )
    return rule(input)
    }
    let input = "012.345.678-90"
    let isValid =
    validate
    (input
    , countElements
    (input
    ) == 14 ? cpf : cnpj
    )
    Funções

    parâmetros constantes

    View full-size slide

  28. func cpf(cpf: String) -> Bool { return ... }
    func unused(input: String) -> Bool { return ... }
    func validate(var input: String, rules: (String -> Bool)...) -> Bool {
    for rule in rules {
    if rule(input) == false {
    return false
    }
    }
    return true
    }
    let input = "012.345.678-90"
    let isValid = validate(input, cpf, unused)
    Funções

    n argumentos

    View full-size slide

  29. func response(sucess: Bool)(status: Int)(body: String) -> String {
    var message = sucess ? "OK" : "ERROR"
    message += " - Status: \(status)"
    message += " - \(body)"
    return message
    }
    let created = response(true)(201)
    created("Usuário (\(user.id)) criado com sucesso")
    // OK - Status: 201 - Usuário (1) criado com sucesso
    let fail = response(false)
    let notFound = fail(404)
    notFound("Usuário (\(user.id)) não encontrado")
    // ERROR - Status: 404 - Usuário (1) não encontrado
    Funções

    currying

    View full-size slide

  30. sasa
    Closures

    View full-size slide

  31. Closures
    var names = [
    "Chris"
    , "Ana"
    , "Danny"
    , "Bob"
    ]
    let sortedNames =
    sorted
    (names
    , { (first:
    String
    , second: String
    ) -> Bool in
    return first < second
    })

    View full-size slide

  32. Closures
    var names = [
    "Chris"
    , "Ana"
    , "Danny"
    , "Bob"
    ]
    let sortedNames =
    sorted
    (names
    , { first, second
    in first < second })

    View full-size slide

  33. Closures
    var names = [
    "Chris"
    , "Ana"
    , "Danny"
    , "Bob"
    ]
    let sortedNames =
    sorted
    (names
    , { $0 < $1 })

    View full-size slide

  34. Closures
    var names = [
    "Chris"
    , "Ana"
    , "Danny"
    , "Bob"
    ]
    let sortedNames =
    sorted
    (names
    , <)

    View full-size slide

  35. Closures
    var names = [
    "Chris"
    , "Ana"
    , "Danny"
    , "Bob"
    ]
    let sortedNames =
    sorted
    (names
    , { (first:
    String
    , second: String
    ) -> Bool in
    return first < second
    })
    let sortedNames =
    sorted
    (names
    , { first, second
    in first < second })
    let sortedNames =
    sorted
    (names
    , { $0 < $1 })
    let sortedNames =
    sorted
    (names
    , <)

    View full-size slide

  36. Closures
    var names = [
    "Chris"
    , "Ana"
    , "Danny"
    , "Bob"
    ]
    let reverseSort = { (first:
    String
    , second: String
    ) -> Bool in
    return first > second
    }
    let reverseSort = { (first:
    String
    , second: String
    ) -> Bool in first > second }
    let reversedNames =
    sorted
    (names
    , reverseSort
    )

    View full-size slide

  37. Enums
    enum CartaoAlelo {
    case Refeição
    case Alimentação
    case FlexCar
    case Auto
    case Cultura
    }
    enum Colors : Int {
    case Yellow = 0xffc100
    case Blue = 0x3970d1
    case Green = 0x256560
    case Purple = 0x7f2a89
    case Teal = 0x00a693
    }

    View full-size slide

  38. Enums
    enum Colors : Int {
    case Yellow = 0xffc100
    case Blue = 0x3970d1
    case Green = 0x256560
    case Purple = 0x7f2a89
    case Teal = 0x00a693
    func uicolor(_ a: CGFloat = 1.0) -> UIColor {
    let r = CGFloat((self.toRaw() >> 16) & 0xFF) / 255.0
    let g = CGFloat((self.toRaw() >> 8) & 0xFF) / 255.0
    let b = CGFloat((self.toRaw() >> 0) & 0xFF) / 255.0
    return UIColor(red: r, green: g, blue: b, alpha: a)
    }
    }
    let y = Colors.Yellow // (Enum Value)
    y.toRaw() // 16.761.088
    var label = UILabel()
    label.textColor = Colors.Yellow.uicolor()
    label.textColor = Colors.Blue.uicolor(0.6)

    View full-size slide

  39. Enums
    enum Carta: Int {
    case Ás = 1
    case Dois, Três, Quatro, Cinco, Seis, Sete, Oito, Nove, Dez
    case Valete, Rainha, Rei
    func description() -> String {
    switch self {
    case .Ás:
    return "Ás"
    case .Valete:
    return "Valete"
    case .Rainha:
    return "Rainha"
    case .Rei:
    return "Rei"
    default:
    return String(self.toRaw())
    }
    }
    }
    let a = Carta.Ás
    a.toRaw() // 1
    a.description() // "Ás"
    let b = Carta.Cinco
    b.toRaw() // 5
    b.description() // "5"

    View full-size slide

  40. Enum
    enum ColorSpace {
    case RGB(Int, Int, Int)
    case CMYK(Float, Float, Float, Float)
    func description() -> String {
    switch self {
    case .RGB(let r, let g, let b):
    return "R: \(r), G: \(g), B: \(b)"
    case .CMYK(let c, let m, let y, let k):
    return "C: \(c), M: \(m), Y: \(y), K: \(k)"
    }
    }
    }
    let red = ColorSpace.RGB(255, 0, 0)
    println(red.description())
    // R: 255, G: 0, B: 0
    let orange = ColorSpace.CMYK(0.0, 25.88, 70.98, 0.0)
    println(orange.description())
    // C: 0.0, M: 25.87999, Y: 70.98000, K: 0.0

    View full-size slide

  41. Enums
    enum Planet: Int {
    case Mercury =
    1, Venus, Earth, Mars
    case Jupiter, Saturn, Uranus, Neptune
    func description() ->
    String {
    return [
    "Mercury"
    , "Venus"
    , "Earth"
    , "Mars"
    ,
    "Jupiter"
    , "Saturn"
    , "Uranus"
    , "Neptune"
    ][self
    .toRaw
    () - 1]
    }
    }
    let e = Planet
    .Earth
    println
    (e.description
    ()) // Earth
    println
    (e.toRaw
    ()) // 3
    if let s = Planet
    .fromRaw
    (6) {
    println
    (s.description
    ()) // Saturn
    }

    View full-size slide

  42. sasa
    Classes e Structs

    View full-size slide

  43. Classes e Structs

    ambos
    : atributos, métodos, construtores,
    protocolos, extensões

    classes: herança, destrutor

    classes por referência,
    structs por valor

    String
    , Array, Dictionary = structs

    View full-size slide

  44. Classes e Structs
    struct Point {
    var x = 0.0
    var y = 0.0
    }
    var p = Point()
    p.x = 31.41
    p.y = 27.18
    var p2 = Point(x: 31.41, y: 27.18)
    class Location {
    var lat = 0.0
    var lng = 0.0
    }
    var l = Location()
    l.lat = 31.41
    l.lng = 27.18

    View full-size slide

  45. Classes e Structs
    class Location {
    var lat, lng: Double
    var name = ""
    init() {
    lat = 0.0
    lng = 0.0
    }
    init(latitude lat: Double, longitude lng: Double) {
    self.lat = lat
    self.lng = lng
    }
    init(latitude lat: Double, longitude lng: Double, name: String) {
    self.lat = lat
    self.lng = lng
    self.name = name
    }
    }
    var a = Location()
    // {lat 0.0 lng 0.0 name ""}
    var b = Location(latitude: 3.14, longitude: 2.71)
    // {lat 3.14 lng 2.71 name ""}}
    var c = Location(latitude: 3.14, longitude: 2.71, name: "X")
    // {lat 3.14 lng 2.71 name "X"}}

    View full-size slide

  46. Classes e Structs
    class User {
    var firstName = ""
    var lastName = ""
    var name: String {
    return firstName + " " + lastName
    }
    init(firstName f: String, lastName l: String) {
    firstName = f
    lastName = l
    }
    }
    var u = User(firstName: "Jean", lastName: "Pimentel")
    u // {firstName "Jean" lastName "Pimentel"}
    u.name // "Jean Pimentel"

    View full-size slide

  47. Classes e Structs
    class User {
    var firstName = ""
    var lastName = ""
    lazy var address = Address()
    init(firstName f: String, lastName l: String) {
    firstName = f
    lastName = l
    }
    }
    var u = User(firstName: "Jean", lastName: "Pimentel")
    u // {firstName "Jean" lastName "Pimentel" nil}
    u.address
    u // {firstName "Jean" lastName "Pimentel" {Address}}

    View full-size slide

  48. Classes e Structs
    class User {
    var firstName = ""
    var lastName = ""
    lazy var address: Address = self.loadAddress()
    init(firstName f: String, lastName l: String) {
    firstName = f
    lastName = l
    }
    func loadAddress() -> Address {
    // API request, DB request etc
    return Address()
    }
    }
    var u = User(firstName: "Jean", lastName: "Pimentel")
    u // {firstName "Jean" lastName "Pimentel" nil}
    u.address
    u // {firstName "Jean" lastName "Pimentel" {Address}}

    View full-size slide

  49. sasa
    Protocols

    View full-size slide

  50. Protocols

    classes, structs e enums

    protocolos podem herdar protocolos

    podem definir atributos e métodos

    View full-size slide

  51. Protocols
    protocol Togglable {
    mutating func toggle()
    }
    enum Switch : Int, Togglable {
    case Off, On
    mutating func toggle() {
    switch self {
    case Off:
    self = On
    case On:
    self = Off
    }
    }
    }
    var lightSwitch = Switch.Off
    lightSwitch.toRaw() // 0
    lightSwitch.toggle()
    lightSwitch.toRaw() // 1

    View full-size slide

  52. Protocols
    protocol Card {
    var user: User { get set }
    var number: Int { get set }
    var balance: Double { get }
    func credit(value: Double)
    func debit(value: Double)
    func getBalance() -> Double
    }

    View full-size slide

  53. sasa
    Extensions

    View full-size slide

  54. Extensions

    categories do Objective-C

    classes, structs e enums

    View full-size slide

  55. Extensions
    extension CGRect {
    init(center: CGPoint, width: CGFloat, height: CGFloat) {
    let x = center.x - (width/2)
    let y = center.y - (height/2)
    self.init(x: x, y: y, width: width, height: height)
    }
    }
    // CGRect(x: Double, y: Double, width: Double, height: Double)
    var rect = CGRect(center: CGPoint(x: 160, y: 200), width: 100, height: 200)

    View full-size slide

  56. Extensions
    extension String {
    var length: Int {
    return countElements(self)
    }
    subscript(i: Int) -> Character? {
    if i < 0 || i >= length {
    return nil
    }
    return self[advance(startIndex, i)]
    }
    }
    var s = "Jean"
    s.length // 4
    s[2] // {Some "e"}
    s[8] // nil
    var e = "\u{1F1EB}\u{1F1F7}"
    e.utf16Count // 4
    e.length // 1

    View full-size slide

  57. sasa
    Interoperabilidade

    View full-size slide

  58. Interoperabilidade

    C/C++ não é permitido em
    Swift
    , devendo ser encapsulado em
    Objective-C

    CoreFoundations
    podem ser usados diretamente

    id são mapeados para
    AnyObject
    Swift Obj-C
    Limitações

    View full-size slide

  59. sasa
    Problemas

    View full-size slide

  60. Problemas

    sem documentação
    (em comparação à Obj-C
    )

    beta, alterações diárias,
    BC Break

    performance
    (10x – 100x mais lento)

    View full-size slide

  61. Problemas

    Crashes
    – github.com/practicalswift/swift-compiler-crashes

    Incompleta
    – github.com/ksm/SwiftInFlux

    View full-size slide

  62. sasa
    Conclusões

    View full-size slide

  63. Conclusão
    Podemos usar?

    View full-size slide