Trilhas
/
Swift
Swift
/
Exercícios
/
Mestre da lasanha
Mestre da lasanha

Mestre da lasanha

Exercício de aprendizagem

Introdução

Valores padrão de parâmetros

Valores padrão 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, logo após a anotação de tipo do parâmetro. Quando um valor padrão de parâmetro é especificado, quem chama a função pode omitir esse parâmetro na chamada, e o valor padrão será usado no lugar.

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

Parâmetros variádicos permitem que uma função aceite zero ou mais valores de um tipo especificado para um único parâmetro. Você 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 esses 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
Note

Se uma função incluir parâmetros adicionais depois de um parâmetro variádico, o primeiro parâmetro seguinte ao parâmetro variádico precisa ter um rótulo de argumento explícito, para que o Swift saiba onde termina a lista de argumentos variádicos.

Parâmetros in-out

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 gera um erro de compilação. Se uma função quiser modificar o valor de um parâmetro, ela precisa usar um parâmetro in-out para tornar essa mutabilidade explícita.

Para usar parâmetros in-out, quem programa precisa ter certeza de três coisas:

  1. A definição da função precisa marcar explicitamente os parâmetros in-out escrevendo a palavra-chave inout entre os : e o nome do tipo na anotação de tipo do parâmetro.
  2. O valor passado para o parâmetro in-out precisa ser declarado como uma variável, não como uma constante. Da mesma forma, ele não pode ser um literal.
  3. O nome da variável precisa ser precedido por um & na chamada da função, marcando-o explicitamente como modificável.

Quando isso é feito, a função cria uma cópia interna do parâmetro in-out, modifica essa cópia conforme indicado no corpo da função e, quando a função retorna, 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")
Existem algumas regras extras que você deve conhecer a respeito de parâmetros in-out.

1. Dentro de uma função com parâmetros in-out, você não pode 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)` gera um erro do compilador.

Funções aninhadas

No Swift, você pode definir funções dentro de outras funções. Essas são conhecidas como funções aninhadas.

Funções aninhadas costumam ser usadas como auxiliares privadas que realizam tarefas específicas para a função que as contém, sem poluir o escopo externo:

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

Funções aninhadas se comportam como funções normais, mas sua visibilidade fica restrita ao corpo da função que as contém.

Instruções

Neste exercício, você vai escrever mais um pouco de código para ajudar a preparar a sua lasanha incrível daquele seu livro de receitas favorito.

Você tem cinco tarefas, todas relacionadas ao tempo gasto preparando a lasanha.

1. Permitir alterar o tempo esperado no forno

Você quer escrever uma função remainingMinutesInOven melhorada que recebe como parâmetro o número de minutos decorridos que a lasanha está no forno e retorna quantos minutos a lasanha ainda precisa ficar no forno, com base no tempo esperado no forno em minutos da tarefa anterior. Antes, você dependia de um valor constante, expectedMinutesInOven, que vinha de fora da função remainingMinutesInOven. Isso deixava as coisas um pouco bagunçadas demais para o seu gosto e não era flexível o bastante, já que não permitia alterar o tempo esperado no forno.

Para organizar tudo, defina a função remainingMinutesInOven que recebe como parâmetro o número de minutos decorridos que a lasanha está no forno, além de um parâmetro expectedMinutesInOven com valor padrão 40. Sua função deve retornar quantos minutos a lasanha ainda precisa ficar 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

2. Permitir números diferentes de camadas

Você havia escrito antes uma função preparationTimeInMinutes que recebe como parâmetro o número de camadas que você adicionou à lasanha e retorna quantos minutos você gastou preparando a lasanha, supondo que cada camada leva 2 minutos para preparar. No entanto, você não está muito satisfeito com essa função, já que precisa contar sozinho o número de camadas da sua lasanha antes de chamá-la, e quem tem tempo para tudo isso?

Para facilitar a sua vida, escreva uma função, preparationTimeInMinutes, que recebe um parâmetro variádico do tipo String, layers, no qual você lista as diferentes camadas da sua lasanha. A função então conta o número de camadas da sua lasanha e retorna a quantidade de tempo de preparo necessária.

preparationTimeInMinutes(layers: "sauce", "noodles")
// Returns 4
preparationTimeInMinutes(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns 24

3. Calcular as quantidades de massa e molho

Antes de começar a montar a sua lasanha, você quer ter certeza de que tem molho e massa suficientes para montar a lasanha dos seus sonhos. Para cada camada de massa da sua lasanha, você vai precisar de 3 folhas de massa. Para cada camada de molho da sua lasanha, você vai precisar de 0,2 litro de molho.

Defina a função quantities que recebe um parâmetro variádico do tipo String, layers, no qual você lista as diferentes camadas da sua lasanha. A função então determina a quantidade de massa e de molho necessária para preparar a sua refeição. O resultado deve ser retornado em uma tupla 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)

4. Converter litros em onças fluidas no local

Infelizmente, o molho que você tem em mãos está com o volume indicado em onças fluidas em vez de litros. Para ajudar a saber se você tem molho suficiente em mãos, escreva uma função, toOz, que recebe um parâmetro de tupla in-out, (noodles: Int, sauce: Double), e converte a quantidade de molho para onças fluidas. Repare 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)

5. Determinar o melhor vinho para servir

Por fim, você quer saber que tipo de vinho servir com a sua lasanha. Você ouviu dizer que deve servir vinho branco se houver mais mussarela, ricota e bechamel na lasanha do que carne e molho, e vinho tinto caso contrário. Escreva uma função redWine que recebe um parâmetro variádico do tipo String, layers, no qual você lista as diferentes camadas da sua lasanha. A função vai usar cinco funções aninhadas para determinar o número de camadas de mussarela, ricota, bechamel, molho e carne na lasanha, e comparar os números de camadas para determinar se o vinho tinto deve ser servido, retornando true se sim e false se não.

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
Editar via GitHub O link abre em uma nova janela ou aba
Swift Exercism

Tudo pronto para começar Mestre da lasanha?

Crie sua conta no Exercism para aprender e dominar Swift com 35 conceitos116 exercícios e mentoria humana de verdade, tudo de graça.