A Linguagem Swift

A Linguagem Swift

Dd958da4c68b7d3227b3f1cd92a429a6?s=128

Jean Pimentel

December 17, 2014
Tweet

Transcript

  1. None
  2. Swift Swift = Objective-C - C

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

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

  5. Swift Swift = Objective-Haskell

  6. Criador Chris Lattner Criador do ecossistema LLVM Diretor do departamento

    Developer Tools Julho 2010 Julho 2013  Setembro 2014 1.0
  7. O que muda? ~80% da complexidade no desenvolvimento para iOS/OSX

    está no Cocoa
  8. Legibilidade • sem [ ] para métodos • sem ;

    • if obriga uso de { } – If ... { ... } • condicionais explícitas – if (meuObjeto) vs if meuObjeto != nil { … }
  9. Tipagem • Forte • Estática • Inferida • Tipo Opcional

    T? enum Optional<T> { case None, Some(T) }
  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
  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]
  12. Tipagem var a: Int // nil a = 1 //

    1 a = nil // ERROR var b: Int? // nil b = 5 // {Some 5} b = nil // nil
  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" }
  14. Mutabilidade • NSMutableArray vs NSArray • NSMutableDictionary vs NSDictionary •

    NSMutableString vs NSString
  15. Mutabilidade • NSMutableArray vs NSArray • NSMutableDictionary vs NSDictionary •

    NSMutableString vs NSString var vs let
  16. Mutabilidade var str = "Olá" // "Olá" str += ",

    mundo!" // "Olá, mundo!" let hello = "Hello" // "Hello" hello = "Hello, world!" // ERROR
  17. sasa Tuplas

  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"
  19. sasa Switch/Case

  20. Switch, Case • sem break • fallthrough explícito

  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; }
  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”) }
  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") }
  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") } }
  25. sasa Funções

  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!"
  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
  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
  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
  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
  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
  32. sasa Closures

  33. Closures var names = [ "Chris" , "Ana" , "Danny"

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

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

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

    , "Bob" ] let sortedNames = sorted (names , <)
  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 , <)
  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 )
  39. sasa Enums

  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 }
  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)
  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"
  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
  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 }
  45. sasa Classes e Structs

  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
  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
  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"}}
  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"
  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}}
  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}}
  52. sasa Protocols

  53. Protocols • classes, structs e enums • protocolos podem herdar

    protocolos • podem definir atributos e métodos
  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
  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 }
  56. sasa Extensions

  57. Extensions • categories do Objective-C • classes, structs e enums

  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)
  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
  60. sasa Interoperabilidade

  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
  62. sasa Problemas

  63. Problemas • sem documentação (em comparação à Obj-C ) •

    beta, alterações diárias, BC Break • performance (10x – 100x mais lento)
  64. Problemas • Crashes – github.com/practicalswift/swift-compiler-crashes • Incompleta – github.com/ksm/SwiftInFlux

  65. sasa Conclusões

  66. Conclusão Podemos usar?