() translation by (you can also view the original English article)
Para fazer algo na Swift, você precisará aprender as entradas e saídas das funções. Funções são excepcionalmente poderosas e flexíveis em Swift. São basicamente simples — especialmente se você já trabalhou com outras linguagens de programação antes — mas por causa da sintaxe flexível do Swift você pode facilmente se perder, caso não esteja familiarizado com o básico.
Neste artigo, vamos focar primeiro nos conceitos básicos e explorar sintaxe mais complexa e casos de uso no próximo artigo. É importante você não enroscar no básico, por serem essenciais para entender de onde vem o poder da função em Swift. Vamos começar com um exemplo para analisar a anatomia de uma função em Swift.
1. Aprender com exemplo
Uma função nada mais é do que um bloco de código que pode ser executada sempre que necessário. Eu gostaria de começar com um exemplo para discutir a anatomia básica de uma função em Swift. Vá até o Xcode e crie um novo playground. Adicione a seguinte definição de função ao playground.
1 |
func printHelloWorld() { |
2 |
println("Hello World!") |
3 |
}
|
Uma função começa com a palavra-chave func
e é seguida do nome da função, printHelloWorld
no nosso exemplo. Como em muitas outras linguagens, o nome da função é seguido por parênteses que contêm os parâmetros da função, a entrada da função.
O corpo da função é cercado por chaves. A função printHelloWorld
contém uma declaração a qual imprimi a string Hello World!
na saída padrão. Isso é como uma função básica se parece em Swift. A sintaxe é simples, limpa e minimalista.
Você pode chamar a função digitando o nome da função, seguido por parênteses.
1 |
printHelloWorld() |
2. Parâmetros
Vamos deixar o exemplo acima um pouco mais complexo, adicionando parâmetros á definição da função. Isso significa simplesmente que oferecemos a função com valores de entrada que podem ser usados no corpo da função. No exemplo a seguir, definimos a função printMessage
, que aceita um parâmetro, message
, do tipo String
.
1 |
func printMessage(message: String) { |
2 |
println(message) |
3 |
}
|
Uma função pode aceitar vários parâmetros ou valores de entrada. Os parâmetros são envolvidos por parênteses após o nome da função. O nome do parâmetro é seguido por dois-pontos e o tipo do parâmetro. Como você se lembra, isso é muito semelhante a declarar uma variável ou constante. Simplesmente diz que o parâmetro message
é do tipo String
.
Em vez de imprimir uma string codificada como fizemos na função printHelloWorld
, imprimimos o valor do parâmetro message
. Isso torna a função mais útil e flexível.
Chamar a função é muito semelhante ao que vimos anteriormente. A única diferença é que passamos um argumento ao chamar a função.
1 |
printMessage("Hello World!") |
Observe que os termos parâmetros e argumentos são usados frequentemente como sinônimos, mas há uma diferença sutil na semântica em Swift. No Swift, parâmetros são os valores especificados na definição de função, enquanto os argumentos são os valores passados para a função quando ela é chamada.
Múltiplos parâmetros
Como mencionado anteriormente, a sintaxe das funções é muito flexível e não deveria se surpreender que é perfeitamente possível passar vários argumentos para uma função. No próximo exemplo, criamos uma variação da função printMessage
que nos permite imprimir a mensagem várias vezes.
1 |
func printMessage(message: String, times: Int) { |
2 |
for i in 0..<times { |
3 |
println("\(i) \(message)") |
4 |
}
|
5 |
}
|
Enquanto o nome da função é idêntico da função original printMessage
, o tipo da função é diferente. É importante você entender a sentença anterior. Leia novamente.
Cada função tem um tipo, constituído de tipos de parâmetro e o tipo de retorno. Exploraremos os tipos de retorno em instantes. Funções podem ter o mesmo nome desde que seu tipo seja diferente, como mostram as definições das duas funções anteriores.
O tipo da primeira função é (String)-> ()
enquanto o tipo da segunda função é (String, Int)-> ()
. O nome de ambas as funções é o mesmo. Não se preocupe com o símbolo ->
. Seu significado se tornará claro em alguns instantes, quando discutirmos os tipos de retorno.
A segunda função printMessage
define dois parâmetros, message
do tipo String
e times
do tipo Int
. Esta definição ilustra uma das características que Swift tem adotada de Objective-C, nome de funções/métodos legíveis. Enquanto o nome da função é printMessage
, lendo os nomes dos parâmetros da função, é fácil de entender o que a função supostamente faz.
Na segunda função printMessage
, nós criamos um laço for-in
para imprimir a strings message
, times
vezes. Nós usamos o operador de intervalo semi-aberto, ..<
, como vimos no início desta série.



Quando começamos a digitar printMessage
no playground, o Xcode exibe as duas funções no menu de AutoCompletar. Graças ao tipo da função, é fácil escolher a função que estamos interessados. Chamar a segunda função printMessage
é tão simples como:
1 |
printMessage("Hello World", 3) |
Valores padrão
Um dos meus recursos favoritos é a capacidade de definir valores padrão para parâmetros. Isso pode parecer bobo, se você está vindo de uma linguagem que tem esse recurso há séculos, mas isso é ótimo se você tem trabalhado com C e Objective-C, por muitos anos.
Resumindo, Swift permite aos desenvolvedores definir valores padrão para os parâmetros de uma função. Vamos definir uma nova função que imprime a data atual em um formato específico. Certifique-se de que você adicionou a seguinte instrução de importação na parte superior do seu playground para importar o framework UIKit.
1 |
import UIKit |
Vamos primeiro definir a função de printDate
sem fazer uso de valores padrão para qualquer um dos parâmetros.
1 |
func printDate(date: NSDate, format: String) { |
2 |
let dateFormatter = NSDateFormatter() |
3 |
dateFormatter.dateFormat = format |
4 |
println(dateFormatter.stringFromDate(date)) |
5 |
}
|
Se você não estiver familiarizado com o framework Foundation e você não está entendendo o que está acontecendo no corpo da função, então tudo bem. O foco deste exemplo não é sobre a implementação da formatação da data. Em printDate
, usamos o valor do parâmetro format
para formatar o valor de date
. Se não passarmos um valor para o parâmetro format
, o Swift irá nos informar mostrando um erro.



Podemos resolver esta situação, definindo um valor padrão para o segundo parâmetro da função, conforme a definição da função atualizada abaixo.
1 |
func printDate(date: NSDate, format: String = "YY/MM/dd") { |
2 |
let dateFormatter = NSDateFormatter() |
3 |
dateFormatter.dateFormat = format |
4 |
println(dateFormatter.stringFromDate(date)) |
5 |
}
|
Definir um valor padrão é tão simples como especificar um valor na lista de parâmetros na definição da função. O resultado é que o Swift não vai reclamar e o erro desaparece.
1 |
printDate(NSDate()) |
E se nós quisermos passar um valor para o parâmetro de format
? Vamos testar e ver o que o Swift nos diz.



Como o parâmetro format
tem um valor padrão, e é opcional, precisamos passar o nome do argumento para dizer ao Swift a qual parâmetro estamos nos referindo. A correção é muito simples, como você pode ver abaixo.
1 |
printDate(NSDate(), format: "dd/MM/YY") |
Note que a Apple recomenda que os parâmetros com um valor padrão sejam posicionados no final da lista de parâmetros. Esta é certamente uma boa idéia e comum na maioria das outras linguagens de programação que oferecem suporte a parâmetros opcionais.
3. Tipo de retorno
As funções que vimos até agora não retornam nada quando a chamamos. Vamos fazer a função printDate
mais útil, retornando a data formatada como uma string, em vez de imprimir a data formatada de dentro da função. Isso requer duas mudanças, como você pode ver abaixo.
1 |
func printDate(date: NSDate, format: String = "YY/MM/dd") -> String { |
2 |
let dateFormatter = NSDateFormatter() |
3 |
dateFormatter.dateFormat = format |
4 |
return dateFormatter.stringFromDate(date) |
5 |
}
|
A primeira coisa que nós mudamos é a definição da função. Após a lista de parâmetros especificamos o tipo do retorno, String
. O tipo de retorno é precedido pelo símbolo ->
. Se você já trabalhou com CoffeeScript, então isso vai parecer familiar.
Em vez de imprimir a data formatada usando a função println
, usamos o palavra-chave return
para retornar o valor da função. Isso é tudo que precisamos fazer. Vamos testá-lo.
1 |
let formattedDate = printDate(NSDate(), format: "dd/MM/YY") |
2 |
|
3 |
println(formattedDate) |
Chamamos a função printDate
, armazenamos o valor retornado na constante formattedDate
e vamos imprimir o valor de formattedDate
na saída padrão. Observe que o nome da função printDate
já não reflete o que ele faz, então você pode querer alterá-lo para formatDate
.
Nenhum tipo de retorno
As outras funções que definimos neste tutorial não tem um tipo de retorno. Quando uma função não tem um tipo de retorno, não é necessário incluir o símbolo ->
na definição de função.
Alguns parágrafos atrás, eu disse que nenhuma das funções que tinha definido retornava um valor para nós. Isso não é inteiramente verdade. Deixe-me explicar os detalhes essenciais com um experimento. Adicione a seguinte linha ao seu playground e veja o que acontece.



Isto é interessante. O Swift não da um erro que nós armazenamos o valor de retorno da função printHelloWorld
em uma constante, mas informa que é incapaz de identificar o tipo do valor
da constante.
O que está acontecendo aqui? Toda função em Swift retorna um valor, mesmo se nós não definimos um tipo de retorno na definição de função. Quando uma função não especifica explicitamente um tipo de retorno, a função implicitamente retorna Void
, o que equivale a uma tupla vazia, ou ()
para ser breve. Você pode ver isso no painel de saída do playground, como mostrado na imagem acima.
Podemos nos livrar do aviso acima declarando explicitamente o tipo de valor
, uma tupla vazia. Concordo que não é muito útil armazenar uma tupla vazia em uma constante, mas ilustra que toda função tem um valor de retorno.
1 |
let value: () = printHelloWorld() |
Tuplas
Outra grande característica do Swift é a capacidade de retornar multiplos valores a partir de uma função, retornando uma tupla. O exemplo a seguir ilustra como isto funciona. Deixe-me repetir que não é importante que você entenda como a função timeComponentsForDate
funciona. O foco é o valor de retorno da função timeComponentsForDate
, uma tupla com três elementos.
1 |
func timeComponentsForDate(date: NSDate) -> (hour: Int, minute: Int, second: Int) { |
2 |
let dateComponents = NSCalendar.currentCalendar().components((.CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond), fromDate: date) |
3 |
let hour = dateComponents.hour |
4 |
let minute = dateComponents.minute |
5 |
let second = dateComponents.second |
6 |
return (hour, minute, second) |
7 |
}
|
A função aceita um argumento, uma instância de NSDate
e retorna uma tupla com três valores rotulados. Rotular valores da tupla é apenas para sua comodidade, é possível omitir os rótulos.
1 |
func timeComponentsForDate(date: NSDate) -> (Int, Int, Int) { |
2 |
let dateComponents = NSCalendar.currentCalendar().components((.CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond), fromDate: date) |
3 |
let hour = dateComponents.hour |
4 |
let minute = dateComponents.minute |
5 |
let second = dateComponents.second |
6 |
return (hour, minute, second) |
7 |
}
|
No entanto, como o exemplo a seguir ilustra, rotular os valores da tupla retornada pela função é muito conveniente e torna seu código mais fácil de entender.
1 |
let timeComponents = timeComponentsForDate(NSDate()) |
2 |
|
3 |
println(timeComponents.hour) |
4 |
println(timeComponents.minute) |
5 |
println(timeComponents.second) |
Também é possível retornar um valor opcional de uma função, se há situações em que a função não tem valor para retornar. Isto é tão simples como definir o tipo de retorno da função como opcional como mostrado abaixo.
1 |
func timeComponentsForDate(date: NSDate) -> (hour: Int, minute: Int, second: Int)? { |
2 |
let dateComponents = NSCalendar.currentCalendar().components((.CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond), fromDate: date) |
3 |
let hour = dateComponents.hour |
4 |
let minute = dateComponents.minute |
5 |
let second = dateComponents.second |
6 |
return (hour, minute, second) |
7 |
}
|
Conclusão
Neste tutorial, focamos nos conceitos básicos de funções no Swift. É importante que você entenda a sintaxe das funções, porque no próximo artigo iremos explorar funções mais avançadas baseadas no que já abordamos neste tutorial.
Aconselho a ler o artigo novamente se necessário e, mais importante, escrever algumas funções em um playground para se familiarizar com a sintaxe. Os princípios básicos são fáceis de entender, mas você só pega o jeito deles, praticando.
Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!