Pílula K #05 — Funções
Nesta pílula, abordaremos toda a base para que você entender sobre funções em Kotlin, desde sua estrutura até recursos mais elaborados que ajudarão você a escrever um código melhor. Então, simbora e toma essa dose!
O que é uma função?
Uma função é como um pequeno programa que tem seu próprio nome e pode ser executado (invocado) chamando esse nome a partir de outra função. É a maneira mais básica de organizar seus programas e reutilizar o código. Você passa informações para uma função, e a função usa essas informações para calcular e produzir um resultado.
A estrutura básica de uma função é:
fun nomeDaFuncao(p1: Tipo1, p2: Tipo2, ...): TipoRetorno {
// linhas de código
return resultado
}
Aqui, nomeDaFuncao
é o nome da função, e p1
, p2
, ... são os parâmetros da função. Cada parâmetro tem um nome de identificador (por exemplo, p1
, p2
) seguido de dois pontos e o tipo desse parâmetro. O parêntese de fechamento da lista de parâmetros é seguido por dois pontos e o tipo de resultado produzido pela função.
As linhas de código no corpo da função são cercadas por chaves. A expressão após a palavra-chave return
é o resultado que a função produz quando termina.
Um parâmetro é como você define o que é passado para uma função, é o espaço reservado. Um argumento é o valor real que você passa para a função. A combinação de nome, parâmetros e tipo de retorno é chamada de assinatura da função.
Uma função de exemplo
Aqui está uma função simples chamada multiplicarPorDois()
:
fun multiplicarPorDois(x: Int): Int {
println("Dentro da função multiplicarPorDois")
return x * 2
}
fun main() {
val r = multiplicarPorDois(5)
println(r)
}
/* Saída
10
*/
Aqui, multiplicarPorDois()
recebe um parâmetro Int
e retorna um Int
. As linhas entre as chaves são o corpo da função. A última linha retorna o valor de seu cálculo x * 2
como o resultado da função.
O código da função é executado invocando-o através do nome multiplicarPorDois()
(como uma abreviação para esse código). É por isso que as funções são a forma mais básica de simplificação e reutilização de código na programação. Você também pode pensar em uma função como uma expressão com valores substituíveis (os parâmetros).
println()
também é uma chamada de função, apenas acontece de ser fornecida pelo Kotlin. Nos referimos a funções definidas pelo Kotlin como funções de biblioteca.
Tipos de Retorno Unit e Explícitos
Se a função não fornecer um resultado significativo, seu tipo de retorno é Unit
. Você pode especificar Unit
explicitamente se quiser, mas o Kotlin permite que você o omita:
fun dizerOla() {
println("Iae manolos!")
}
fun dizerAdeus(): Unit { //Agora explicitando o tipo de retorno Unit
println("Vlw Flw!")
}
fun main() {
dizerOla()
dizerAdeus()
}
/* Saída
Iae manolos!
Vlw Flw!
*/
Tanto dizerOla()
quanto dizerAdeus()
retornam Unit
, mas dizerOla()
deixa de fora a declaração explícita. A função main()
também retorna Unit
.
Corpo de expressão
Se uma função é apenas uma única expressão, você pode usar a sintaxe abreviada de um sinal de igual seguido da expressão:
fun nomeDaFuncao(arg1: Tipo1, arg2: Tipo2, ...): TipoRetorno = expressão
Um corpo de função cercado por chaves é chamado de corpo de bloco. Um corpo de função usando a sintaxe de igual é chamado de corpo de expressão.
Aqui está um exemplo de uma função que usa um corpo de expressão:
fun multiplicarPorTres(x: Int): Int = x * 3
fun main() {
println(multiplicarPorTres(5))
}
/*Saída
15
*/
Esta é uma versão curta de dizer return x * 3
dentro de um corpo de bloco. O Kotlin infere o tipo de retorno de uma função que tem um corpo de expressão.
Dica: Nomes Descritivos
pelo amor de Jah!! cuida com os nomes…
Ao escrever funções, escolha nomes descritivos. Isso torna o código mais fácil de ler e muitas vezes pode reduzir a necessidade de comentários de código.
fun calcular(x: Int, y: Int): Int{
return x / y
}
fun multiplicarValores(valorA: Int, valorB: Int): Int {
return valorA * valorB
}
fun main(){
calcular(6,2)
multiplicarValores(6,2)
}
/*Saída
3
12
*/
Uéh… passei os mesmos parâmetros para calcular e deu direfentes resultados, o que "calcular" faz afinal? […] " aaahhh… ele divide. Então porque não mudar o nome para 'dividirValores'? "
Essas coisinhas que podem acontecer no seu dia a dia que são rapidamente imperceptíveis e consomem seu tempo (porque vai ter de pesquisar e entender o que de fato a função faz), sendo que um nome melhor já resolveria.
Sobrecarga de Funções
A sobrecarga de funções é a capacidade de definir várias funções com o mesmo nome, mas com parâmetros diferentes. Isso permite que você dê a uma única função vários significados, dependendo do contexto em que é usada. Aqui está um exemplo:
fun somarValores(x: Int, y: Int): Int {
return x + y
}
fun somarValores(x: Double, y: Double): Double {
return x + y
}
fun main() {
val a = somarValores(1, 2)
val b = somarValores(3.0, 4.0)
println(a)
println(b)
}
/*Saída
3
7.0
*/
Observe como existem duas funções chamadas somarValores
, mas uma recebe parâmetros Int
e retorna um Int
, enquanto a outra recebe parâmetros Double
e retorna um Double
. Isso nos permite usar o mesmo nome de função para duas operações diferentes.
Valores Padrão de Parâmetro
Os valores padrão de parâmetro permitem que você especifique um valor padrão para um parâmetro. Se o chamador não fornecer um valor para esse parâmetro, o valor padrão é usado em seu lugar. Aqui está um exemplo:
fun dizerOla(nome: String = "Mundo") {
println("Olá, $nome!")
}
fun main() {
dizerOla()
dizerOla("Kotlin")
}
/*Saída
Olá, Mundo!
Olá, Kotlin!
*/
Observe como a função dizerOla
recebe um parâmetro nome
, mas atribuímos um valor padrão de "Mundo"
. Isso significa que, se não passarmos um valor para nome
, "Mundo"
será usado em seu lugar. Isso nos permite fornecer um comportamento padrão para nossas funções.
Iaí? O que achou das funções? Agora você pode organizar seu código e o reutilizá-lo em diferentes contextos. Nesta dose, cobrimos o básico do básico das funções, sua estrutura, parâmetros, tipos de retorno e alguns recursos mais elaborados como sobrecarga de funções e valor padrão de parâmetro. Na próxima dose iremos ver um recurso dahora e pouco usado nas funções: "função infixa".