Os conceitos básicos sobre funções e procedimentos foram visto em Portugol: Funções e Portugol: Procedimentos da linguagem Portugol. A leitura é recomenda.

O uso de funções com os tipos de dado Struct, podem ser vistos nas seções Struct.

O assunto ponteiros para função em Go pode ser visto em Ponteiro para Função.

Procedimentos em Go, assim como em várias outra linguagens, são funções que não retornam nenhum tipo de valor ao término de sua execução.

Sintaxe
func nome_procedimento()
{
  //corpo procedimento
}
Onde
func: palavra reservada que define uma procedimento ou função.

Para invocar um procedimento, utilizamo seu próprio nome no local desejado.

Exemplo 1
package main
import "fmt"

func procedimento() {
	fmt.Printf("procedimento")
}

func main() {
	procedimento()
}
Saída
procedimento

Função diferente de procedimento, retornam um valor durante a sua execução ou ao seu fim. Qualquer tipo de dado estudado dentre os já estudados pode ser utilizado como retorno.

Sintaxe
func nome()  (tipo_retorno){
	//corpo
    return valor
}
Onde
tipo_retorno: Tipo de dado que será retornado pela função. Primitivo ou não
return: Comando para retornar um valor de uma função
Exemplo 2
package main
import "fmt"

func funcao() string {
	return "string"
}

func main() {
	retorno := funcao()
	fmt.Printf(retorno)
}
Saída
string

As funções e procedimentos podem ser criados antes ou depois da função main, levando em consideração que possuímos apenas um arquivo .go contendo um função main.

Diferente de linguagens como C e C++ não precisamos declarar protótipos antes da função main.

Exemplo 3
package main
import "fmt"

func main() {

	retorno := funcao()
	fmt.Printf(retorno)
}

func funcao() string {
	return "retorno"
}
Saída
retorno

Em uma futura seção, vamos aprender a separa os nossos programas em arquivos .go para melhor organização. A utilização do exemplo acima foi feita apenas para compreensão, não sendo utilizadas para programas mais complexos.

Para a passagem de argumentos para funções em Go, semelhante a outras linguagens de programação, declaramos todos os parâmetros de acordo com a sintaxe abaixo:

Sintaxe
func nome_funcao(param1 tipo_param1, paramN tipo_paramN) tipo_retorno1 {
	//corpo
}
func nome_funcao(param1 tipo_param1, paramN tipo_paramN) (tipo_retorno1,tipo_retornoN){
	//corpo
}
Onde
tipo_dado: tipo de dado do parâmetro
nome_funcao: nome da função desejada
tipo_retorno: tipo de dado de retorno
param1..N: lista de parâmetros separados por vírgula
tipo_param1..N: tipo de dado do parâmetro
tipo_retorno1..N: tipo de dado do retorno da função
Exemplo 4
package main
import "fmt"

func main() {

	retorno := funcao(2)
	fmt.Println(retorno)
}

func funcao(param int) int {
	return param * 2
}
Saída
4

Caso uma função possua dois ou mais parâmetros declarados com um mesmo tipo de dado, a omissão do tipo de dado pode ser feita com exceção do tipo de dado do último parâmetro.

Sintaxe
nome_funcao(param1, param2,paramN tipo_retorno) {
//corpo
}
Exemplo 5
package main
import "fmt"

func main() {

	retorno := funcao(2, 2, 2)
	fmt.Println(retorno)
}

func funcao(param1, param2, param3 int) int {
	return param1 * param2 * param3
}
Saída
8

Em Go é possível passarmos vários parâmetros de um mesmo tipo sem a necessidade informar cada um deles individualmente. Isso é possível graças ao uso de "…" como parâmetro de uma função e em conjunto como argumento.

É importante observar que o uso de "..." deve ser sempre utilizado como parâmetro único ou último dos parâmetros definidos para uma função.

Sintaxe
func name_funcao(params...tipo_dado) {
	//corpo
}
Onde
params: parametros separados por (,) ou vetores e slices
tipo_dado: tipo de dado único para todos os parâmetros contidos em params
Exemplo 6
package main

import "fmt"

func varios_params(minhas_strings ...string) {
	for i, item := range minhas_strings {
		fmt.Printf("[%d] %s \n", i, item)
	}
}

func main() {

	valor := []string{"vetor", "com", "strings", "para", "teste"}
	varios_params(valor...)
	fmt.Printf("\n")
	varios_params("varios", "parametros", "passados", "para", "...")
}
Saída
[0] vetor 
[1] com 
[2] strings
[3] para 
[4] teste 

[0] varios 
[1] parametros 
[2] passados 
[3] para 
[4] ...

Por padrão, Go não permite o uso do operador (...) para diferentes tipos de dados. Para tal, é necessário utilizar uma interface:

Sintaxe
func nome_funcao(nome_parametro ...interface{}){
//corpo
}
Exemplo 7
package main
import "fmt"

func show(params ...interface{}) {
	for _,i := range params{
	    fmt.Print(i)
	}
}

func main() {
	show("teste",1,true,3,"Z",5,6,7)
}
Saída
teste1true3Z567

A passagem de argumento por referencia e valor já foram visto em Portugol e em Tutorial C: Funções.

Quando simplesmente passamos um valor ou variável como argumento para uma função estamos passando apenas seu valor. Depois de usado internamente na função através do parâmetro, esse valor será destruído.

Exemplo 8
func funcao(valor int) {
  valor = valor*2
}

func main() {
   valor :=10 
   fmt.Printf("Antes: %d \n",valor)
   funcao(valor)
   fmt.Printf("Depois: %d",valor)
}
Saída
Antes: 10 
Depois: 10

Para passarmos um valor por referência, precisamos informar a referência da variável que desejamos alterar seu valor, como argumento a uma função desejada. O operador & deve ser usado no início no nome da variável passada como argumento. Dentro da função, o operador * deve ser usado para acessar o valor da variável passando como argumento.

Exemplo 9
package main

import "fmt"

func funcao(param *int) {
	*param = 2 //alterando o valor da variável pelo seu ponteiro
}

func main() {
	valor := 10
	fmt.Printf("Antes: %d \n", valor)
	funcao(&valor) //alterada internamente
	fmt.Printf("Depois: %d", valor)
}
Saída
Antes: 10 
Depois: 2

Para que uma função retorne mais de uma valor, precisamos especificar quais tipos de dados desejamos retornar. Esses devem estar entre ( e ) e separados por (,). O comando return deve ser usado apenas uma vez separando cada valor retornado.

Sintaxe
func nome_funcao(param1 tipo_param1, paramN tipo_paramN) (tipo_retorno1,tipo_retornoN,...){
	//corpo
    return valor1,valorN
}
Onde
tipo_retorno1...N: Tipo de dado que será retornado pela função. Primitivo ou não
return: Comando para retornar um valor de uma função
valor1...N: um ou mais valores retornados

A linguagem Go permite a associação de uma nome a um tipo de retorno de uma função como pode ser visto na sintaxe abaixo. Dessa forma, são criadas variáveis locais nas quais podemos atribuir seus respectivos valores de retorno que posteriormente são retornadas automaticamente ao utilizarmos o comando return apenas.

Sintaxe
func nome_funcao(param1 tipo_param1, paramN tipo_paramN) (nome_retorno1 tipo_retorno1, nome_retorno2 tipo_retornoN,...){
	//corpo
    return 
}
Onde
tipo_dado: tipo de dado do parâmetro
param1..N: lista de parâmetros separados por vírgula
nome_retorno1..N: Nome das variáveis para retorno
tipo_param1..N: tipo de dado do parâmetro
tipo_retorno1..N: tipo de dado do retorno da função
Exemplo 10
func funcao(valor int) (dobro int,triplo int) {
  dobro = valor*2 
  triplo = valor*3
  return //dobro, triplo não necessários
}

func main() {
   var valor,valor2 = funcao(10)
   fmt.Printf("Val: %d %d",valor,valor2)
}
Saída
dobro:20 triplo:30

Caso em um determinada situação seja necessário descartar algum retorno de uma função ou do comando range , por exemplo, a linguagem Go fornece o identificador (_) para tal situação.

Exemplo 7
package main
import "fmt"

valores := [3] int {1, 4, 7}
for _, valor := range valores { //descartando índice
     fmt.Printf("%d \n",valor)
}
Saída
1 
4 
7 
Exemplo 11
package main
import "fmt"

func funcao(param int) (int, int) {
	return param * 2, param * 3
}

func main() {
	var valor int
	_, valor = funcao(10)
	fmt.Printf("%d \n", valor)
	valor, _ = funcao(10)
	fmt.Printf("%d", valor)
}
Saída
30
20

Ao longo do tutorial vamos nos deparar com funções que retornam mais de uma valor e também o uso do indentificador blank.

  1. 09/04/2025 - revisão 3 - Parâmetros variáveis de tipos diferentes
  2. 16/09/2024 - revisão 2 - Correção em links Portugol; ajustes gramaticais
  3. 02/10/2023 - revisão 1 - Correção em referências, erros gramaticais, remoção de texto lixo
  4. 21/08/2023 - versão inicial