Skip to content

Latest commit

 

History

History
208 lines (159 loc) · 4.74 KB

funcoes.md

File metadata and controls

208 lines (159 loc) · 4.74 KB

3.5 Funções

As funções em Lua e na maioria das linguagens funcionam como um comando que executa um trecho de código. Nada muito complexo, por exemplo:

function teste()
    print('hello world')
    print(' esse trecho é executado quando chamamos "teste()" ')
end

Depois de definir uma função, basta executar ela como qualquer outro comando:

> teste()
hello world
 esse trecho é executado quando chamamos "teste()" 
>

Argumentos e retornos

Na matemática, funções tem como característica principal receberem um valor X e devolverem um valor Y. Em programação quase sempre seguimos o mesmo raciocínio usando argumentos e retornos.

Seguindo essa analogia, podemos passar valores (equivalente ao X) para dentro da função desse modo:

function duplicado(texto)
    print(texto)
    print(texto)
end

Assim, quando chamarmos essa função, passamos o valor que queremos que texto tenha:

> duplicado('alguma coisa')
alguma coisa
alguma coisa
> 

Já para realizar a o inverso e termos um valor saindo da função (equivalente ao Y), basta usarmos o comando return

function soma(numero1, numero2)
    return numero1 + numero2
end

Desse jeito podemos gravar o valor de saída em uma váriavel ou usar direto em outra função:

> resultado = soma(1, 2)
> print(resultado)
3
>

> print(soma(1, 2))
3
>

Escopo de váriaveis

Um ponto importante na relação entre uso de váriaveis dentro de funções é o escopo de acesso. Quando definimos uma váriavel em Lua, por padrão é definida como "global" e isso causa muitos problemas. Exemplo:

variavel = 'alguma coisa'

function teste()
    variavel = 'outra coisa'
end

Esse código é bem ambíguo e traz muita incerteza do resultado, mas Lua segue o seguinte raciocinio:

  • Gravar 'variavel' com o valor "alguma coisa"
  • Gravar 'teste' com a função:
    • Gravar 'variavel' com o valor "outra coisa"

Nesse ponto, antes de executarmos a função, nossa variavel permanece com o valor original. Mas caso executemos, seu valor vai ser alterado como definimos pra alterar.

> print(variavel)
alguma coisa
> teste()
> print(variavel)
outra coisa
> 

Isso é um problema gigantesco pois quanto mais variaveis tivermos, mais dificil é manter o controle sobre o valor de cada uma e maior é a chance de sobrepor um valor sem querer e causar problemas.

Como evitamos isso?

Simples, basta mudarmos o escopo em que estamos salvando nossas variaveis usando o comando local.

variavel = 'alguma coisa'

function teste()
    local variavel = 'outra coisa'
end

Assim ao invés de trocarmos o valor da variável original, a função cria uma variável temporária dentro dela qua some assim que a função termina.

> print(variavel)
alguma coisa
> teste()        
> print(variavel)
alguma coisa

Além de evitar conflitos entre uso de variáveis, quando a função encerra e a variável temporária some, a memória que a variável ocupava fica limpa e nosso programa fica mais leve. Sempre que puder, tente criar apenas variáveis locais e evite ao máximo salvar algo em escopo global.

Extra

Uma parte engraçada mas que pode ser útil é que funções funcionam como qualquer outro tipo de valor. Isso significa que outro jeito de definir uma função em Lua é assim:

printSoma = function(x1, x2) print(x1 + x2) end

Que seria o mesmo que escrever:

function printSoma(x1, x2)
    print(x1 + x2)
end

Mas lógico que saber disso trás certas vantagens como callbacks e funções locais.

Exemplo de um callback:

function soma(x1, x2, callback)
    local resultado = x1 + x2
    callback(resultado)
end

Assim podemos escolher qual função callback vai ser através do argumento que passarmos:

> soma(2, 3, print)
5

Isso seria o mesmo que substituir o argumento callback pelo comando print. Mas também podemos usar funções próprias como callback:

function duplicado(valor)
    print(valor)
    print(valor)
end

function soma(x1, x2, callback)
    local resultado = x1 + x2
    callback(resultado)
end
> soma(2, 3, duplicado)
5
5
> 

Outra coisa interessante que podemos fazer é criarmos funções locais:

function teste(x1, x2)
    local function duplicado(valor)
        print(valor)
        print(valor)
    end
    duplicado(x1 + x2)
end

Assim a função duplicado() só existe dentro do escopo da função teste().

> teste(3, 4)
7
7
> duplicado('alguma coisa')
stdin:1: attempt to call global 'duplicado' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?
> 

Próximo: