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. Criador Chris Lattner Criador do ecossistema LLVM Diretor do departamento

    Developer Tools Julho 2010 Julho 2013  Setembro 2014 1.0
  2. Legibilidade • sem [ ] para métodos • sem ;

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

    T? enum Optional<T> { case None, Some(T) }
  4. Tipagem var k = 1024 // 1,024 var M =

    1_048_576 // 1,048,576 var G: Int G = k * M // 1,073,741,824
  5. 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]
  6. Tipagem var a: Int // nil a = 1 //

    1 a = nil // ERROR var b: Int? // nil b = 5 // {Some 5} b = nil // nil
  7. 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" }
  8. Mutabilidade var str = "Olá" // "Olá" str += ",

    mundo!" // "Olá, mundo!" let hello = "Hello" // "Hello" hello = "Hello, world!" // ERROR
  9. 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"
  10. 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; }
  11. 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”) }
  12. 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") }
  13. 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") } }
  14. 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!"
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. Closures var names = [ "Chris" , "Ana" , "Danny"

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

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

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

    , "Bob" ] let sortedNames = sorted (names , <)
  24. 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 , <)
  25. 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 )
  26. 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 }
  27. 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)
  28. 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"
  29. 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
  30. 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 }
  31. 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
  32. 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
  33. 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"}}
  34. 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"
  35. 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}}
  36. 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}}
  37. Protocols • classes, structs e enums • protocolos podem herdar

    protocolos • podem definir atributos e métodos
  38. 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
  39. 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 }
  40. 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)
  41. 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
  42. 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
  43. Problemas • sem documentação (em comparação à Obj-C ) •

    beta, alterações diárias, BC Break • performance (10x – 100x mais lento)