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. View Slide

  2. Swift
    Swift = Objective-C
    - C

    View Slide

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

    View Slide

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

    View Slide

  5. Swift
    Swift = Objective-Haskell

    View Slide

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

    Setembro
    2014
    1.0

    View Slide

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

    View Slide

  8. Legibilidade

    sem [ ] para métodos

    sem ;

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

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

    View Slide

  9. Tipagem

    Forte

    Estática

    Inferida

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

    View Slide

  10. 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 Slide

  11. 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 Slide

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

    View Slide

  13. 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 Slide

  14. Mutabilidade

    NSMutableArray vs NSArray

    NSMutableDictionary vs NSDictionary

    NSMutableString vs NSString

    View Slide

  15. Mutabilidade

    NSMutableArray vs NSArray

    NSMutableDictionary vs NSDictionary

    NSMutableString vs NSString
    var vs let

    View Slide

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

    View Slide

  17. sasa
    Tuplas

    View Slide

  18. 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 Slide

  19. sasa
    Switch/Case

    View Slide

  20. Switch, Case

    sem break

    fallthrough explícito

    View Slide

  21. 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 Slide

  22. 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 Slide

  23. 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 Slide

  24. 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 Slide

  25. sasa
    Funções

    View Slide

  26. 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 Slide

  27. 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 Slide

  28. 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 Slide

  29. 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 Slide

  30. 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 Slide

  31. 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 Slide

  32. sasa
    Closures

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. 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 Slide

  38. 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 Slide

  39. sasa
    Enums

    View Slide

  40. 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 Slide

  41. 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 Slide

  42. 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 Slide

  43. 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 Slide

  44. 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 Slide

  45. sasa
    Classes e Structs

    View Slide

  46. 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 Slide

  47. 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 Slide

  48. 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 Slide

  49. 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 Slide

  50. 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 Slide

  51. 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 Slide

  52. sasa
    Protocols

    View Slide

  53. Protocols

    classes, structs e enums

    protocolos podem herdar protocolos

    podem definir atributos e métodos

    View Slide

  54. 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 Slide

  55. 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 Slide

  56. sasa
    Extensions

    View Slide

  57. Extensions

    categories do Objective-C

    classes, structs e enums

    View Slide

  58. 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 Slide

  59. 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 Slide

  60. sasa
    Interoperabilidade

    View Slide

  61. 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 Slide

  62. sasa
    Problemas

    View Slide

  63. Problemas

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

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

    performance
    (10x – 100x mais lento)

    View Slide

  64. Problemas

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

    Incompleta
    – github.com/ksm/SwiftInFlux

    View Slide

  65. sasa
    Conclusões

    View Slide

  66. Conclusão
    Podemos usar?

    View Slide