Escolar Documentos
Profissional Documentos
Cultura Documentos
Teaching LP 20172 Seminario Swift PDF
Teaching LP 20172 Seminario Swift PDF
Laisa Martins
Lucas Lopes
Nathânia Queiroz
1
Introdução
2
História
● Uma linguagem recente, introduzida ao mundo em 2014
● Criada pela Apple, veio da necessidade de adequar o desenvolvimento para iOS e OS X aos
padrões, tendências e necessidades atuais
● Objective-C era a linguagem utilizada para desenvolver para iOS e OS X, mas ela ainda era
uma camada “fina” que cobria a linguagem C. Em comparação aos paradigmas atuais da
programação, Objective-C, apesar de moderna e inovadora na época da sua criação,
apresenta algumas lacunas
● Swift nasce prometendo substituir Objective-C oferecendo mais eficiência, clareza para
facilitar o aprendizado, portabilidade, segurança…
3
História
● No seu lançamento em 2014, a Apple prometeu fazer da linguagem uma plataforma de
código aberto em breve
● A promessa foi cumprida em 2015. Além do código, a empresa lançou um blog sobre a
linguagem e um manual completo disponível online e para download
4
Visão Geral e Objetivos
● A criação de Swift busca trazer modernidade para a programação para iOS e OS X
● A Apple espera que Swift se torne uma das principais linguagens de programação nos
próximos 20 anos
● Swift se propõe ser uma linguagem mais fácil, segura e completa. Ou seja: uma linguagem
que atraia mais público e atenda as necessidades do mundo corporativo
● A linguagem é compilada
5
Visão Geral e Objetivos
● Linguagem possui clareza na sintaxe; uma escrita limpa, que facilita o aprendizado
6
Começando a Programar
● Possui uma plataforma online disponibilizada pela IBM
○ https://swift.sandbox.bluemix.net/
● A plataforma será descontinuada em janeiro de 2018 devido aos avanços da computação
em nuvem, agora é mais fácil experimentar diretamente nesses ambientes
● A Apple oferece binários para OS X e Linux que podem compilar código para iOS, OS X,
watchOS, tvOS e Linux
● Podemos usar a interface interativa pelo terminal digitando swift, ou podemos criar um
arquivo com extensão .swift e executar no terminal swift arquivo.swift
7
Curiosidades
Um algoritmo comum de busca, por exemplo, obtém o resultado muito mais rápido
com Swift.
8
Amarrações
9
Identificadores
● Podem começar com: caracteres maiúsculos e minúsculos de A – Z, underscore (_),
caracteres alfanuméricos Unicode não combinados do Plano Básico
10
Identificadores
● Dentro de uma Closure sem nomes explícitos de parâmetros, estes são nomeados por
default como $0, $1, etc. Portanto dentro do escopo da Closure, é permitido iniciar com o
caractere $
● É possível usar palavras reservadas como identificadores, usando o caractere ` antes e
depois.
Exemplo:
class = palavra reservada, identificador inválido
`class` = identificador válido
-> Note que o caractere ` não pertence ao identificador, portanto X e `X` tem o
mesmo significado.
11
Palavras-chave
Usadas em declarações:
12
Palavras-chave
Usadas em statements:
13
Palavras-chave
Usadas em tipos e expressões:
14
Palavras-chave
Iniciadas com símbolos:
15
Palavras-chave
Reservadas em contextos particulares:
16
Valores e Tipos de dados
17
Sistemas e Tipos
● Possui Tipagem Estática.
● Fortemente tipada.
● Inferência de tipo.
● Possui Case-sensitive.
● Aceita Emoticons.
● Suporta Unicode, os nomes podem ter acento.
18
Variáveis e Constantes
● variáveis são representadas por var e constantes por let
● variáveis são mutáveis, constantes não
let qtdConstante = 1
qtdConstante = 2 // Erro de compilação
19
Sistemas e Tipos
var sea = "abc" abc true
var Sea = true
print(sea, Sea)
var chão = “de terra” 1.0
//aã2 = 1010 Erro de compilação
let sparklingHeart = "\u{1F496}"
// sparklingHeart = "\u{2665}"
print(sparklingHeart)
let = " "
print( )
var str¨12 = 1010.2
str¨12 = 1
print(str¨12)
20
Sistemas e Tipos
● Os nomes constantes e variáveis não podem conter caracteres de espaço em
branco, símbolos matemáticos, setas, pontos de código Unicode de uso privado
(ou inválidos), ou caracteres de desenho de linha e caixa( ╠). Nem podem
começar com um número, embora os números possam ser incluídos em outro
lugar dentro do nome.
let π = 3.14159
let 你好 = "你好世界"
let = "dogcow"
21
Principais Tipos de Dados
● Inteiros (Int)
● Ponto Flutuante (Double e Float)
● Carácter (Character)
● String
● Lógico (Bool)
● Nulo (nil/Optionals)
● Coleções de Tipos( Arrays, Tuplas, Conjuntos, Dicionários, Enumerado)
22
Tipo Inteiro
● A linguagem provê inteiros com e sem sinal, nas formas de 8, 16, 32 e 64 bits.
● Podemos acessar os valores mínimos e máximos de cada tipo inteiro com min e
max
23
Tipo Inteiro
● Swift possui um tipo padrão que varia o tamanho dinamicamente de acordo com
a plataforma atual
● Plataformas 32 bits, Int possui o mesmo tamanho que Int32, assim como UInt
possui o mesmo que UInt32.
● Idem para plataformas 64 bits.
24
Ponto Flutuante
● Double representa um número de ponto flutuante de 64 bits, e Float representa
um de 32 bits.
● Por padrão, na inferência é atribuído sempre Double.
print(valor is Double)
25
Literais Numéricos
Inteiros podem ser escritos como decimal, binário, octal e hexadecimal;
26
Literais Numéricos
let decimalInteger = 17 17
let binaryInteger = 0b10001 // 17 em 17
binário
let octalInteger = 0o21 // 17 em octal
let hexadecimalInteger = 0x11 // 17 em
hexa
print(binaryInteger)
print(hexadecimalInteger)
27
Literais Numéricos
● Pontos Flutuantes podem ser decimais(sem prefix) ou hexadecimais(com prefixo
0x)
● Floats decimais podem ter um expoente opcional, indicado por um e maiúsculo
ou minúsculo. Floats hexadecimais utilizam um p
○ 1.25e2 significa 1.25 x 102, ou 125.0. (e é base 10)
○ 1.25e-2 significa 1.25 x 10-2, ou 0.0125.
○ 0xFp2 significa 15 x 22, ou 60.0. (p é base 2)
○ 0xFp-2 significa 15 x 2-2, ou 3.75.
28
Literais Numéricos
● Possuem formatação extra para melhor redigibilidade (uso de _ ).
let decimalDouble = 12.1875 12.1875 12.1875 12.1875
let exponentDouble = 1.21875e1 1000000
1000000.0000001
let hexadecimalDouble = 0xC.3p0
let umMilhão = 1_000_000
let maisQueUmMilhão = 1_000_000.000_000_1
print(decimalDouble, exponentDouble,
hexadecimalDouble)
print(umMilhão)
print(maisQueUmMilhão)
29
Booleans
● Possui valores true e false
30
Strings e Caracteres
● Uso de \ para alguns caracteres especiais na string
print(barraInvertida+"\n", tab+"\n",
quebraLinha+"\n", aspas)
31
Strings e Caracteres
● Strings Multilines(“ ” ”)
● Strings como vetor de caracteres
● Concatenação (+, +=) e comparação(==) de Strings
● Escapes (\\, \t, \0, \n, \r, \”, \’)
● Unicode (\u{n}), n possui de 1 a 8 dígitos em Hexadecimal
● Principais métodos: append(), count, isEmpty, startIndex, endIndex,
index(before:), index(after:), index(_:offsetBy:), insert(_:at:), remove(at:)
● Iteração com laço for
32
Strings e Caracteres
let multilineString = """ There is a house in New Orleans
There is a house \ They call the Rising Sun
in New Orleans Cat!
They call the Rising Sun Linguagem de Programação
"""
print(multilineString)
33
Strings e Caracteres
let caféDeUmJeito = "caf\u{E9} é bom" são iguais
let caféDeOutroJeito = "caf\u{65}\u{301} são diferentes
\u{65}\u{301} bom"
if(caféDeUmJeito == caféDeOutroJeito) {
print("são iguais")
} else {
print("são diferentes")
}
let latimLetraA: Character = "\u{41}"
let cirilicoLetraA: Character = "\u{0410}"
if latimLetraA != cirilicoLetraA {
print("são diferentes")
}
34
Strings e Caracteres
var dog = "Dogs" D
for character in dog { o
print(character) g
} s
Dogs
dog.append(" ") Dogs are better than cats
print(dog)
35
Optionals
● É um tipo que representa nil ou um valor empacotado
● Podemos declarar uma variável com um sinal de interrogação (?) após o tipo
para dizer ao compilador que ela aceitará o valor nil além de um valor do tipo
especificado.
● Importante para lidar com retorno de funções
● Optional é uma enumeração de dois casos, Optional.none que é equivalente ao
nil, e Optional.some(Wrapped) que armazena o valor empacotado
● Desempacotamento feito através do operador de exclamação (!), ou por
controle de fluxo
36
Optionals
var inteiro: Int? = 1 1 Optional<Int>
inteiro = nil
var Inteiro: Optional<Int> = 1
Inteiro = nil // Erro!
37
Optionals
let stringNumero1 = "1" 2
let numeroInteiro1 = Int(stringNumero1)
let soma = numeroInteiro1! + 1
print(soma)
38
Arrays
● Coleção de dados indexados por inteiros de 0 a N- 1, onde N é o tamanho da
coleção
● Arrays são fortemente tipados, ou seja, só podem conter elementos de mesmo
tipo
● Possui iteração com laço for
● Principais métodos: isEmpty, append(), insert(_:at:), remove(at:),
removeLast(), count, sort(),
39
Arrays
var vetorPar = [2, 4, 6] 3
print(vetorPar.count) [6, 2, 4]
vetorPar.insert(6, at: 0) 6
vetorPar.remove(at:3) 2
print(vetorPar) 4
for item in vetorPar { [1, 2, 3, 4, 5, 6]
print(item)
}
var vetor:[Int] = [1, 3, 5]
vetor += vetorPar
vetor.sort()
print(vetor)
40
Arrays
var frase = [String]() Item 1: My
frase = ["My", "mother", "was", "a", "tailor"] Item 2: mother
Item 3: was
for (index, value) in frase.enumerated() { Item 4: a
print("Item \(index): \(value)") Item 5: tailor
}
41
Dicionários
● São vetores associativos
● Armazena pares com chave e valor (key : value)
● No momento da indexação, retornam o tipo da chave , opcional, porque
pode ser que a chave não exista. Por isso para acessar o valor de uma
chave precisamos desempacotar a entrada com “if let”
● Possui iteração com laço for
● Principais métodos: count, isEmpty, updateValue(_:forKey:),
removeValue(forKey:), values, keys
42
Dicionários
var preços = Dictionary<String,Double>() ["café": 5.0, "açúcar": 3.0, "filtro": 2.5]
preços = ["café":5.00, "açúcar":3.00, ["café": 5.5, "filtro": 2.5, "açúcar": 4.0,
"filtro":2.50 ] "cafeteira": 89.900000000000006]
["café": 5.5, "açúcar": 4.0]
print(preços)
preços["cafeteira"] = 89.90
preços["açúcar"] = 4.00
preços.updateValue(5.50, forKey: "café")
print(preços)
preços["filtro"] = nil
preços.removeValue(forKey:"cafeteira")
print(preços)
43
Dicionários
for (chave, valor) in preços { preço do café é: R$5.5
print("preço do \(chave) é: R$\(valor) ") preço do açúcar é: R$4.0
}
5.5
let preçoDoCafé = preços["café"] O preço do açúcar é: R$ 4.0
print(preçoDoCafé!)
if let preçoDoAçúcar = preços["açúcar"] {
print("O preço do açúcar é: R$ \(preçoDoAçúcar)")
}
44
Conjuntos
● Usado para armazenar informações onde a ordem não importa
● Armazena valores distintos de um mesmo tipo
● Possui os fundamentos básicos de Conjuntos (União, Interseção, Diferença
Simétrica, Subtração)
● Principais métodos: isEmpty, count, insert(), remove(), contains(),
intersection(), symmetricDifference(), union(), subtracting(), sorted()
45
Conjuntos
● intersection(_:) cria um novo
conjunto com os valores em
comum entre os dois outros
● symmetricDifference(_:) cria um
novo conjunto com os valores
dos dois, exceto valores em
comum
● union(_:) cria um conjunto com
todos os valores dos dois
conjuntos, mas não repete
● subtracting(_:) cria um conjunto
com valores que não pertence ao
outro conjunto
46
Conjuntos
var conjunto1 = Set<Int>() [7, 2, 3, 1]
conjunto1.insert(1) [1]
conjunto1.insert(7) [2, 3]
var conjunto2: Set = [1, 2, 3] [7, 2, 3]
print(conjunto1.union(conjunto2)) 1
print(conjunto1.intersection(conjunto2)) 2
print(conjunto2.subtracting(conjunto1)) 3
print(conjunto1.symmetricDifference(conjunto2))
47
Enumerados
● Possui uma sintaxe mais completa do que nas outras linguagens
● Podem armazenar valores de tipos diferentes
enum Bussola {
case Norte, Sul, Leste, Oeste
}
var direção = Bussola.Sul // inferência do tipo Bussola
direção = .Norte
enum horarioAula {
case NoHorario
case Atrasado(Int) // atrasado alguns minutos
}
48
Enumerados
func descrição(status: horarioAula) { A aula começou no horário certo
switch status { A aula está atrasada 10 minutos
case .NoHorario:
print("A aula começou no horário certo ")
case .Atrasado(let min):
print("A aula está atrasada \(min) minutos")
}
}
var status = horarioAula.NoHorario
descrição(status: status)
status = .Atrasado(10)
descrição(status: status)
49
(Des)Alocação de memória
● A alocação de tipos primitivos é feita na pilha, os tipos compostos ou de
coleções são alocados no monte mas o compilador pode alocá-los na
pilha para otimizar o processo em alguns casos
● A desalocação pode ser feita pelo programador para classes utilizando o
método deinit, ou ela será feita pelo coletor de lixos ARC(Automatic
Reference Counting)
● ARC é um contador de referências
50
Entrada e Saída
● Linha de comando
○ print() para output
○ readLine() para input
● Arquivos, utilizando FileManager do Foundation:
let response = readLine()
let arquivo: FileHandle? = FileHandle(forReadingAtPath: response!)
//LEITURA DO ARQUIVO:
if arquivo != nil {
let dados = arquivo?.readDataToEndOfFile()
}
51
Entrada e Saída
let componentes = NSString(data: dados!, encoding:
String.Encoding.utf8.rawValue)
52
Serialização
● É possível utilizando um protocolo chamado Codable
● Utiliza dois protocolos chamados Encodable e Decodable que fazem o
encode e decode do dado para/de uma representação externa.
53
Expressões e Comandos
54
Operadores
● Podem ser unários, binários ou ternários
● Operadores de atribuição:
let b = 10
let (x, y) = (1, 2) // x vale 1 e y vale 2
var a = 5
a = b // a = 10
a += b // a = 20
55
Operadores
● O operador de atribuição não retorna um valor. Evita efeitos colaterais!
if x = y {
// operação inválida!!!
}
56
Operadores
● Operadores aritméticos:
57
Operadores
1 + 2 // 3
10.0 / 2.5 // 4.0
"hello, " + "world" // "hello, world"
9 % 4 // 1
-9 % 4 // -1
2 + 3 % 4 * 5 // 17 (precedência de operadores!)
58
Operadores
● operador unário de menos
●let tres = 3
let menosTres = -tres // -3
●
let menosSeis = -6
let tambemMenosSeis = +menosSeis // -6
59
Operadores
● Operadores de comparação:
● Igual a (a == b) Comparação de tuplas:
● Nâo igual a (a != b) (2, "zebra") < (2, "amor") // false
Usados para objetos que possam referenciar a mesma instância de uma classe:
● Idêntico a (===)
● Não idêntico a (!==)
60
Operadores
● Checagem de tipo is
61
Operadores
● Operadores bitwise:
● not ~
● and &
● or |
● xor ^
● shift left <<
● shift right <<
62
Operadores
● Curto-circuito:
● c = a != nil ? a! : b // b não é avaliado caso a seja diferente de nil
63
Fluxo de controle
● For-in:
let names = ["Ana", "José", "João", "Clotilde"]
for name in names {
print("Olá, \(name)!")
}
●
let numeroDePernas = ["aranha": 8, "formiga": 6, "gato": 4]
for (nomeAnimal, contagemPernas) in numeroDePernas {
print("\(nomeAnimal)s têm \(contagemPernas) pernas")
}
64
Fluxo de controle
● For-in:
65
Fluxo de controle
● While:
while semestre == true {
print(“socorro”)
}
● Repeat-while:
repeat {
print(“socorro”)
} while semestre == true
66
Fluxo de controle
● if e else:
if 1 < 2 {
print(“que bom”)
} else {
print(“como assim?”)
67
Fluxo de controle
● switch:
let umCaractere: Character = "z"
switch umCaractere {
case "a":
print("inicio do alfabeto")
case "g", "h", "i":
print("meio do alfabeto")
fallthrough
case let y where y == “k”:
print(“kkk”)
case "z":
print("final do alfabeto")
default:
print("nao sei")
}
68
Fluxo de controle
● continue:
var presente = 10
while presente > 1 {
if presente == 5 {
continue
}
presente -= 1
}
69
Fluxo de controle
● break:
var presente = 10
while presente > 1 {
if presente == 5 {
break
}
presente -= 1
}
70
Funções
● Estrutura básica:
71
Funções
● Manipulação de retornos - tuplas:
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
●
}
return (currentMin, currentMax)
}
72
Funções
if let extremos = minMax(array: [8, -6, 2, 109, 3, 71]) {
print("min é \(extremos.min) e max é \(extremos.max)") //
Imprime “min é -6 e max é 109”
}
73
Funções
● Rótulo de argumento vs Nome de parâmetro
○ Rótulo de argumento: usado na chamada da função
○ Nome de parâmetro: usado na implementação da função
○ Por default, quando não especificado na definição, o rótulo do argumento é o nome do parâmetro
74
Funções
● Omitindo o rótulo dos argumentos
○ para omitir o rótulo e não precisar explicitá-lo na chamada da função, usar o underscore (_)
75
Funções
● Parâmetros default
func qualquerCoisa(nomeParametroUm: Int, nomeParametroDois: Int = 13) -> Int
{
let soma = nomeParametroUm + nomeParametroDois
return soma
}
let soma = qualquerCoisa(nomeParametroUm: 1)
76
Funções
● Parâmetros default
○ A função print() estipula um parâmetro default \n (chamado terminator),
imprimindo as informações com quebra de linha
○ Para alterar este valor, é preciso chamar a função como print(“olá!”, terminator: “”)
77
Funções
● Parâmetros variantes
○ especificados com reticências (...)
○ para a passagem de um número variado de parâmetros
○ funções devem ter no máximo um parâmetro variante
78
Funções
● Parâmetros In-Out
○ Swift define parâmetros como constantes, imutáveis
○ tentar mudar o valor de um parâmetro no escopo de uma função gera erro de compilção
○ para modificar parâmetros (e fazer com que a mudança permaneça fora da função), definir eles como inout
■ OBS: parâmetros inout devem ser variáveis, não podem ser variantes e não aceitam valores default
func addTwoInts(_ a: Int, _ b: Int) -> Int { // tipo: (Int, Int) -> Int
return a + b
}
○ O tipo função pode ser usado como qualquer outro. Por exemplo, definindo variáveis:
●
var mathFunction: (Int, Int) -> Int = addTwoInts
print("Resultado: \(mathFunction(2, 3))") // Imprime “Resultado: 5”
80
Funções
● Tipos função
○ Estes tipos também podem ser passados como parâmetros de funções
81
Funções
● Funções aninhadas
○ Swift permite funções aninhadas, definidas dentro de outras funções. Por default, as
funções de dentro ficam escondidas do escopo global, mas podem ser chamadas e
usadas pela função de fora
○ As funções de fora podem retornar uma de suas funções aninhadas e assim esta pode
ser usada fora do seu escopo original
82
Funções
● Funções aninhadas
func opera(com simbolo:String) -> (Int, Int) -> Int {
func adicao(num1:Int, num2:Int) -> Int {
return num1 + num2
}
func subtracao(num1:Int, num2:Int) -> Int {
return num1 - num2
}
let operacao = (simbolo == "+") ? adicao : subtracao
return operacao
}
84
Classes e Estruturas
Classes possuem capacidades adicionais que Structs não possuem:
● Herança
● TypeCast permite a identificação do tipo de uma classe
● Deinitializers
● Contadores de referência permitem que mais de uma referência seja feita a uma
instância
85
Estruturas
struct Pessoa {
private var nome: String? func info() -> [String] {
public var telefone: Int var str: [String] = []
internal let endereço : String
if let nome = self.nome {
init (nome: String, telefone: Int, str.append(nome)
endereço: String){ }
self.nome = nome
self.telefone = telefone let telefone = self.telefone
self.endereço = "Serra" str.append(String(telefone))
}
return str
func getNome() -> String? { }
return nome }
} 86
Classes
class Pessoa { func setNome(nome: String) {
self.nome = nome
private var nome: String? }
public var telefone: Int func info() -> [String] {
internal let endereço = "Vitória" var str: [String] = []
//Pode ser nula:
init (telefone: Int, nome: String) { if let nome = self.nome {
self.telefone = telefone str.append(nome)
self.nome = nome }
} let telefone = self.telefone
str.append(String(telefone))
func getNome() -> String? { return str
return nome }
} }
87
Particularidades das classes
//Classe Pessoa possui atributo qtdCafé = "Moderada" e atributo nome é public
class Estudande: Pessoa {
let universidade = "UFES"
init (nome: String, telefone: Int, endereço: String, qtdCafé: String) {
super.init(nome:nome,telefone:telefone,endereço:endereço)
super.qtdCafé = "Alta!"
}
override func info () -> [String] {
var str: [String] = []
if let nome = self.nome {
str.append(nome)
}
let telefone = self.telefone str.append(String(telefone))
str.append (universidade)
return str
}
} 88
Particularidades das classes
class Banco {
static var moedasBanco = 10_000 var jogador: Jogador? =
static func receber(moedas: Int) { Jogador(moedas: 100) O novo jogador
self.moedasBanco += moedas possui: 100 moedas
} print("O novo jogador possui:
} \(jogador!.moedas) moedas") O banco possui
10000 moedas
class Jogador { print("O banco possui
var moedas: Int \(Banco.moedasBanco) moedas")
init(moedas: Int) { Jogador saiu do
self.moedas = moedas jogador = nil jogo
} print("Jogador saiu do jogo")
deinit {
O banco possui
Banco.receber(moedas: moedas) print("O banco possui
10100 moedas
} \(Banco.moedasBanco) moedas")
}
89
Uso de estruturas
Parte do desenvolvedores prefere usar estruturas, ao invés de classe, devido a
alguns fatores como:
● São mais confiáveis para dados pequenos, pois não é referenciado e sim
copiado. É mais seguro criar cópias do que fazer múltiplas referências a
uma instância.
● Menor preocupação com acesso ilegal da memória
90
Extensões
Servem para adicionar funcionalidades de uma forma organizada a classes,
enumeradores, estruturas ou protocolos.
extension Pessoa{
var saudacao: String {return "Ei " + self.getNome()!}
}
91
Protocolos
protocol AddStrings{
func toString() -> String
}
Os protocolos
prometem que uma extension String: Nat
AddStrings{
classe particular
func toString() ->
implemente um String{
conjunto de métodos. return self
}
}
● Módulos
● Arquivos Fonte
● Classes
● Blocos de Código
93
Módulos
Ao importar um módulo ele especificará:
//Importa todo o módulo
● Namespace import Foundation
● Controle de acesso
import PackageDescription
95
Polimorfismo
96
Ad-hoc
● Coerção:
func recebeOpcional(value: Int?) { }
let x: Int = 1
recebeOpcional(value: x) // converte um tipo não opcional para um tipo opcional
// ---------------//
func recebeDouble(value: Double) { }
recebeDouble(value: 2) // converte um Int para um Double (tipo mais amplo); não faz estreitamento
// ---------------//
97
Ad-hoc
● Sobrecarga:
let umInteiro = 1 + 2
let umaString = "hello, " + "world"
// ---------------//
struct Vector2D {
var x = 0.0, y = 0.0
}
extension Vector2D {
static func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
}
let vector = Vector2D(x: 3.0, y: 1.0)
let outroVector = Vector2D(x: 2.0, y: 4.0)
let somaVectors = vector + outroVector
print("soma = \(somaVectors)") // imprime “”soma = Vector2D(x: 5.0, y: 5.0)”
98
Ad-hoc
● Sobrecarga:
func informaValor(_ valor: Int) {
print("Valor = \(valor)")
}
let a = 1
let b = 1.0
99
Universal
● Paramétrico:
○ Parametrização de funções:
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
100
Universal
● Paramétrico:
○ Parametrização de estruturas:
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
var stackOfStrings = Stack<String>()
var stackOfInts = Stack<Int>()
101
Universal
● Inclusão:
class Veiculo {
var velocidadeAtual = 0.0
var descricao: String {
return "Andando a \(velocidadeAtual) km/h"
}
func fazerBarulho() { }
}
class Carro: Veiculo {
var possuiCarroceria = false
}
class Taxi: Carro {
var quantidadeAtualPassageiros = 0
}
102
Exceções
103
Tratamento de erros
● Swift não suporta exceções não checadas
● Os erros são representados com valores que conformam com o protocolo Error
● O tipo enumerado é o mais adequado para se definir erros simples
104
Tratamento de erros
● Há quatro maneiras de tratar exceções:
○ propagar o erro - funções, métodos ou inicializações “throwing”
■ dentro da função:
guard item.count > 0 else {
throw VendingMachineError.outOfStock
}
105
Tratamento de erros
○ tratar o erro com do-catch:
■ uso do try
do {
try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
} catch VendingMachineError.outOfStock {
print("Out of Stock.")
}
106
Tratamento de erros
○ converter o erro para um valor opcional:
■ uso do try?
107
Tratamento de erros
○ descartar a possibilidade de erro, parando a propagação
■ útil quando se tem certeza que o método não causará uma exceção
■ uso do try!
108
Concorrência
109
Concorrência - a classe Thread
○ O framework Foundation oferece uma classe Thread, baseada internamente na
pthread
var t = Thread {
print("Comecei!")
}
t.start()
110
Concorrência - primitivas de sincronização
○ As funcionalidades básicas usadas para sincronizar threads são travas e semáforos
○ NSLock
■ Quando requisitado, adquire o lock ou entra em espera (lock indisponível)
■ A ordem de aquisição dos locks é “unfair”: não é possível garantir que o primeiro
a requisitar será o primeiro a receber
111
Concorrência - primitivas de sincronização
let lock = NSLock()
class LThread : Thread {
var id:Int = 0
convenience init(id:Int){
self.init()
self.id = id
}
override func main(){
lock.lock()
print(String(id)+" acquired lock.")
lock.unlock()
if lock.try() {
print(String(id)+" acquired lock again.")
lock.unlock()
}else{ // If already locked move along.
print(String(id)+" couldn't acquire lock.")
}
print(String(id)+" exiting.")
}
}
112
Concorrência - primitivas de sincronização
var t1 = LThread(id:1)
var t2 = LThread(id:2)
t1.start()
t2.start()
113
Concorrência - primitivas de sincronização
○ NSContidionLock
let cond = NSCondition()
var available = false
var SharedString = ""
class WriterThread : Thread {
override func main(){
for _ in 0..<5 {
cond.lock()
SharedString = " "
available = true
cond.signal()
cond.unlock()
}
}
}
114
Concorrência - primitivas de sincronização
class PrinterThread : Thread {
override func main(){
for _ in 0..<5 {
cond.lock()
while(!available){
cond.wait()
}
print(SharedString)
SharedString = ""
available = false
cond.unlock()
}
}
}
115
Concorrência - primitivas de sincronização
let writet = WriterThread()
let printt = PrinterThread()
printt.start()
writet.start()
116
Concorrência - Grand Central Dispatch (GCD)
○ API que permite executar closures em gurpos de trabalho
○ Funciona através de filas de despacho
○ Utiliza a classe DispatchQueue
○ Cada item submetido a uma queue é processado em um conjunto de threads
administradas pelo sistema
117
Concorrência - Grand Central Dispatch (GCD)
○ Criando uma queue:
118
Concorrência - Grand Central Dispatch (GCD)
○ Modos sync e async:
■ Executa todo o bloco de uma vez
fila1.sync {
for i in 0..<10 {
print(i)
}
}
■ Execução do programa não espera pelo fim da tarefa do bloco
fila1.async {
for i in 0..<10 {
print(i)
}
}
119
Concorrência - Grand Central Dispatch (GCD)
○ Classes definem a prioridade das tarefas. Por ordem mais importante - menos
importante:
■ userInteractive, userInitiated, default, utility, background, unspecified
120
Concorrência - Grand Central Dispatch (GCD)
○ Atributo define concorrência e situação inicial
121
Concorrência - Grand Central Dispatch (GCD)
○ Exemplo geral
122
Avaliação de linguagens
123
Critérios Gerais C C++ Java Swift
124
Critérios Gerais C C++ Java Swift
125
Critérios Gerais C C++ Java Swift
Passagem de Lista variável Lista variável, Lista variável, por Lista variável,
parâmetros e por valor default, por valor valor e por cópia default, por valor e
e por cópia de de referência. por cópia de
referência referência
126
Critérios Gerais C C++ Java Swift
127
Referências
128
● https://developer.apple.com/library/content/documentation/Swift/Conceptual
/Swift_Programming_Language/index.html
● https://developer.apple.com/swift/blog/
● https://www.uraimo.com/2017/05/07/all-about-concurrency-in-swift-1-the-pr
esent/
● https://insights.stackoverflow.com/survey/2017
● https://github.com/apple/swift-evolution/blob/master/proposals/0123-disallo
w-value-to-optional-coercion-in-operator-arguments.md
● https://swift.org/about/
129