Pílula K #05 — Funções

Klaus Dellano
HavanLabs
Published in
5 min readNov 1, 2023

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".

--

--

Klaus Dellano
HavanLabs

Developer Engineer at HAVAN, focusing on Mobile and RFID.