Valores predefinidos de parâmetros podem ser fornecidos para qualquer um dos parâmetros de uma função, atribuindo um valor ao parâmetro na lista de parâmetros a seguir à anotação de tipo do parâmetro. Quando um valor predefinido de parâmetro é especificado, quem chama a função pode omitir esse parâmetro ao chamar a função e o valor predefinido é usado em vez disso.
func greeting(name: String = "guest", duration: Int = 2) -> String {
"Welcome, \(name). Enjoy your \(duration) night stay."
}
greeting(name: "Bobo", duration: 7)
// Returns "Welcome, Bobo. Enjoy your 7 night stay."
greeting(duration: 3)
// Returns "Welcome, guest. Enjoy your 3 night stay."
greeting(name: "Wynona")
// Returns "Welcome, Wynona. Enjoy your 2 night stay."
greeting()
// Returns "Welcome, guest. Enjoy your 2 night stay."
Parâmetros variádicos permitem que uma função aceite zero ou mais valores de um tipo especificado para um único parâmetro.
Define um parâmetro variádico acrescentando três pontos (...) à anotação de tipo do parâmetro.
Dentro do corpo da função, o Swift disponibiliza estes valores como um array do tipo especificado:
import Foundation
func geometricMean(_ numbers: Double...) -> Double {
var total = 1.0
for number in numbers {
total *= number
}
return pow(total, 1.0 / Double(numbers.count))
}
let result = geometricMean(1, 2, 3, 4, 5)
// result is 2.605171084697352
Se uma função incluir parâmetros adicionais depois de um parâmetro variádico, o primeiro parâmetro a seguir ao parâmetro variádico tem de ter uma etiqueta de argumento explícita, para que o Swift saiba onde termina a lista de argumentos variádicos.
Dentro do corpo de uma função, os parâmetros são tratados como constantes, não como variáveis; tentar modificar o valor de um parâmetro dá origem a um erro de compilação. Se uma função quiser modificar o valor de um parâmetro, tem de usar um parâmetro in-out para tornar essa mutabilidade explícita.
Para usar parâmetros in-out, quem programa tem de ter a certeza de três coisas:
inout entre os : e o nome do tipo na anotação de tipo do parâmetro.& na chamada à função, marcando-o explicitamente como modificável.Quando isto é feito, a função faz uma cópia interna do parâmetro in-out, modifica-a conforme indicado no corpo da função e, quando a função devolve, copia o valor modificado de volta para a variável que foi passada.
func updateVersion(_ record: inout (version: Int, title: String)) {
record.version += 1
}
var dbRecord = (version: 2, title: "Exercism")
updateVersion(&dbRecord)
// dbRecord is now (3, "Exercism")
Há mais algumas regras a ter em conta em relação aos parâmetros in-out.
1 Dentro de uma função com parâmetros in-out, não é permitido referenciar a variável que foi passada como parâmetro in-out.
2. A mesma variável não pode ser passada como vários parâmetros in-out na mesma função.
Por exemplo, `inoutFunc(&mutVar, &mutVar)` provoca um erro de compilação.
Em Swift, podes definir funções dentro de outras funções. Estas são conhecidas como funções aninhadas.
As funções aninhadas são comummente usadas como auxiliares privadas que desempenham tarefas específicas para a função que as contém, sem sobrecarregar o âmbito exterior:
func makeNumber(_ number: Int) -> Int {
func double(_ x: Int) -> Int {
x * 2
}
func increment(_ x: Int) -> Int {
x + 1
}
return number.isMultiple(of: 2) ? increment(double(number)) : double(number)
}
print(makeNumber(3)) // Prints 6
print(makeNumber(4)) // Prints 9
As funções aninhadas comportam-se como funções normais, mas a sua visibilidade está restringida ao corpo da função que as contém.
Neste exercício vais escrever mais algum código para te ajudar a cozinhar a tua brilhante lasanha do teu livro de cozinha preferido.
Tens cinco tarefas, todas relacionadas com o tempo gasto a cozinhar a lasanha.
Queres escrever uma função remainingMinutesInOven melhorada que recebe como parâmetro o número de minutos decorridos que a lasanha está no forno e devolve quantos minutos a lasanha ainda tem de permanecer no forno, com base no tempo esperado no forno, em minutos, da tarefa anterior.
Antes, baseavas-te num valor constante, expectedMinutesInOven, que vinha de fora da função remainingMinutesInOven.
Isso era um pouco demasiado confuso para o teu gosto e não era suficientemente flexível, pois não te permitia alterar o tempo esperado no forno.
Para arrumar as coisas, define a função remainingMinutesInOven que recebe como parâmetro o número de minutos decorridos que a lasanha está no forno, bem como um parâmetro expectedMinutesInOven com um valor predefinido de 40.
A tua função deve devolver quantos minutos a lasanha ainda tem de permanecer no forno, com base no tempo esperado no forno, em minutos, da tarefa anterior.
remainingMinutesInOven(elapsedMinutes: 30)
// Returns 10
remainingMinutesInOven(elapsedMinutes: 30, expectedMinutesInOven: 75)
// Returns 45
Tinhas escrito anteriormente uma função preparationTimeInMinutes que recebe como parâmetro o número de camadas que adicionaste à lasanha e devolve quantos minutos gastaste a preparar a lasanha, partindo do princípio de que cada camada demora 2 minutos a preparar.
No entanto, não estás especialmente satisfeito com esta função, porque tens de contar tu próprio o número de camadas da tua lasanha antes de poderes chamar esta função, e quem é que tem tempo para isso?
Para tornar as coisas mais fáceis para ti, escreve uma função, preparationTimeInMinutes, que recebe um parâmetro String variádico, layers, onde listas as diferentes camadas da tua lasanha.
A função vai depois contar o número de camadas da tua lasanha e devolver o tempo de preparação necessário.
preparationTimeInMinutes(layers: "sauce", "noodles")
// Returns 4
preparationTimeInMinutes(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns 24
Antes de começares a montar a tua lasanha, queres certificar-te de que tens molho e massa suficientes para construir a lasanha dos teus sonhos. Para cada camada de massa da tua lasanha, vais precisar de 3 placas de massa. Para cada camada de molho da tua lasanha, vais precisar de 0,2 litros de molho.
Define a função quantities que recebe um parâmetro String variádico, layers, onde listas as diferentes camadas da tua lasanha.
A função vai depois determinar a quantidade de massa e de molho necessária para preparar a tua refeição. O resultado deve ser devolvido num tuplo do tipo (noodles: Int, sauce: Double).
quantities(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns (noodles: 9, sauce: 0.8)
quantities(layers: "sauce", "noodles", "sauce", "noodles", "meat", "noodles", "mozzarella")
// Returns (noodles: 9, sauce: 0.4)
Infelizmente, o molho que tens à mão tem o volume indicado em onças fluidas em vez de litros.
Para te ajudar a saber se tens molho suficiente à mão, escreve uma função, toOz, que recebe um parâmetro de tuplo in-out, (noodles: Int, sauce: Double), e converte a quantidade de molho em onças fluidas.
Repara que há 33,814 onças fluidas por litro.
var amount = (noodles: 9, sauce: 0.8)
toOz(&amount)
amount
// Returns (noodles: 9, sauce: 27.0512)
Por fim, queres saber que tipo de vinho servir com a tua lasanha.
Ouviste dizer que deves servir vinho branco se houver mais mozarela, ricota e béchamel na lasanha do que carne e molho, e vinho tinto caso contrário.
Escreve uma função redWine que recebe um parâmetro String variádico, layers, onde listas as diferentes camadas da tua lasanha.
A função vai usar cinco funções aninhadas para determinar o número de camadas de mozarela, ricota, béchamel, molho e carne na lasanha, e comparar o número de camadas para determinar se deve ser servido vinho tinto, devolvendo true nesse caso e false caso contrário.
redWine(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns true
redWine(layers: "sauce", "noodles", "béchamel", "meat", "mozzarella", "noodles", "ricotta", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns false
Inscreve-te no Exercism para aprenderes e dominares Swift com 35 conceitos116 exercícios, e mentoria humana real, tudo grátis.