---
title: "Sintaxe Básica de Go: Variáveis, Tipos e Funções - Tutorial Completo"
url: "https://golang.com.br/tutoriais/golang-para-iniciantes/golang-sintaxe-basica-variaveis-tipos-funcoes/"
markdown_url: "https://golang.com.br/tutoriais/golang-para-iniciantes/golang-sintaxe-basica-variaveis-tipos-funcoes.MD"
description: "Aprenda a sintaxe de Go na prática: variáveis com :=, 15 tipos de dados, funções com múltiplos retornos, structs e métodos. Exemplos que você pode copiar e rodar."
date: "2026-02-09"
author: ""
---

# Sintaxe Básica de Go: Variáveis, Tipos e Funções - Tutorial Completo

Aprenda a sintaxe de Go na prática: variáveis com :=, 15 tipos de dados, funções com múltiplos retornos, structs e métodos. Exemplos que você pode copiar e rodar.


Neste segundo artigo da série **"Golang para Iniciantes"**, vamos mergulhar nos fundamentos da linguagem. Você aprenderá tudo sobre variáveis, tipos de dados, funções, structs e métodos — os blocos de construção essenciais de qualquer programa Go.

Se você ainda não leu o primeiro artigo, recomendamos começar por lá:

📖 **[← Artigo Anterior: Golang para Iniciantes: Primeiros Passos](./artigo-1-primeiros-passos)**

## Variáveis em Go

Go oferece várias formas de declarar variáveis, desde a forma explícita até a inferência de tipos.

### Declaração Explícita com `var`

A forma tradicional de declarar variáveis:

```go
package main

import "fmt"

func main() {
    // Declaração explícita: var nome tipo = valor
    var nome string = "João"
    var idade int = 30
    var salario float64 = 5000.50
    var ativo bool = true

    fmt.Printf("Nome: %s, Idade: %d, Salário: %.2f, Ativo: %t\n",
        nome, idade, salario, ativo)
}
```

### Declaração com Inferência de Tipo

Go pode inferir o tipo automaticamente:

```go
package main

import "fmt"

func main() {
    // Inferência de tipo: var nome = valor (tipo inferido)
    var nome = "João"      // string
    var idade = 30         // int
    var preco = 99.99      // float64
    var online = true      // bool

    fmt.Printf("Tipo de nome: %T\n", nome)    // string
    fmt.Printf("Tipo de idade: %T\n", idade)  // int
}
```

### Declaração Curta com `:=`

A forma mais comum no dia a dia — apenas dentro de funções:

```go
package main

import "fmt"

func main() {
    // Forma curta: nome := valor (só funciona dentro de funções)
    nome := "João"
    idade := 30
    pi := 3.14159

    fmt.Println(nome, idade, pi)
}
```

> ⚠️ **Importante**: O operador `:=` só pode ser usado dentro de funções. Fora de funções (escopo de pacote), use `var`.

### Declaração Múltipla

Declare várias variáveis de uma vez:

```go
package main

import "fmt"

func main() {
    // Múltiplas variáveis do mesmo tipo
    var x, y, z int = 1, 2, 3

    // Múltiplas variáveis com tipos diferentes
    var (
        nome    string = "Maria"
        idade   int    = 25
        ativo   bool   = true
    )

    // Com inferência
    a, b, c := 1, 2.5, "texto"

    fmt.Println(x, y, z, nome, idade, ativo)
    fmt.Println(a, b, c)
}
```

### Variáveis Não Inicializadas

Em Go, variáveis sempre têm um "zero value":

```go
package main

import "fmt"

func main() {
    var numero int       // 0
    var texto string     // "" (string vazia)
    var booleano bool    // false
    var ponteiro *int    // nil

    fmt.Printf("int: %d, string: %q, bool: %t, ponteiro: %v\n",
        numero, texto, booleano, ponteiro)
}
```

**Zero values padrão:**

| Tipo | Zero Value |
|------|------------|
| `int`, `float` | `0`, `0.0` |
| `string` | `""` (vazia) |
| `bool` | `false` |
| `pointer`, `slice`, `map`, `channel`, `interface` | `nil` |
| `struct` | Campos com seus zero values |

### Constantes com `const`

Valores que não podem ser alterados:

```go
package main

import "fmt"

func main() {
    // Constantes
    const pi = 3.14159
    const versao = "1.0.0"
    const maxUsuarios = 100

    // Constantes agrupadas
    const (
        Segunda = 1
        Terca   = 2
        Quarta  = 3
        Quinta  = 4
        Sexta   = 5
    )

    fmt.Println("PI:", pi)
    fmt.Println("Dias úteis:", Segunda, Terca, Quarta, Quinta, Sexta)
}
```

**Iota** — gerador de constantes incrementais:

```go
package main

import "fmt"

func main() {
    const (
        Domingo = iota  // 0
        Segunda         // 1
        Terca           // 2
        Quarta          // 3
        Quinta          // 4
        Sexta           // 5
        Sabado          // 6
    )

    fmt.Println("Segunda:", Segunda)  // 1
}
```

## Tipos de Dados em Go

Go é uma linguagem estaticamente tipada com tipos básicos claros.

### Tipos Numéricos

```go
package main

import "fmt"

func main() {
    // Inteiros
    var inteiro int = 42           // Plataforma-dependente (32 ou 64 bits)
    var int8bit int8 = 127         // -128 a 127
    var int16bit int16 = 32767     // -32768 a 32767
    var int32bit int32 = 2147483647
    var int64bit int64 = 9223372036854775807

    // Inteiros sem sinal (unsigned)
    var uint8bit uint8 = 255       // 0 a 255
    var uint16bit uint16 = 65535
    var uint32bit uint32 = 4294967295
    var uint64bit uint64 = 18446744073709551615

    // Ponto flutuante
    var flutuante32 float32 = 3.14159
    var flutuante64 float64 = 3.141592653589793

    // Números complexos (raramente usados)
    var complexo complex64 = 1 + 2i
    var complexo128 complex128 = 1 + 2i

    fmt.Printf("int: %d (tipo: %T)\n", inteiro, inteiro)
    fmt.Printf("float64: %f (tipo: %T)\n", flutuante64, flutuante64)
}
```

**Dica**: Use `int` para inteiros gerais e `float64` para ponto flutuante, a menos que tenha requisitos específicos de memória.

### Strings

Strings em Go são sequências imutáveis de bytes:

```go
package main

import "fmt"

func main() {
    // Declaração de strings
    saudacao := "Olá, Mundo!"
    citacao := `Esta é uma string
    com múltiplas linhas
    e "aspas" não precisam ser escapadas`

    // Concatenação
    nome := "João"
    sobrenome := "Silva"
    nomeCompleto := nome + " " + sobrenome

    // Tamanho
    tamanho := len(saudacao)

    // Acesso a caracteres (retorna byte)
    primeiro := saudacao[0]  // 'O' (byte)

    fmt.Println(nomeCompleto)
    fmt.Println("Tamanho:", tamanho)
    fmt.Printf("Primeiro caractere: %c\n", primeiro)

    // String como slice de bytes
    for i, c := range saudacao {
        fmt.Printf("Índice %d: %c\n", i, c)
    }
}
```

### Booleanos

```go
package main

import "fmt"

func main() {
    var ativo bool = true
    inativo := false

    // Operações lógicas
    resultado1 := ativo && inativo  // AND: false
    resultado2 := ativo || inativo  // OR: true
    resultado3 := !ativo            // NOT: false

    fmt.Println(resultado1, resultado2, resultado3)
}
```

## Operadores

### Operadores Aritméticos

```go
package main

import "fmt"

func main() {
    a, b := 10, 3

    fmt.Println("Soma:", a+b)        // 13
    fmt.Println("Subtração:", a-b)   // 7
    fmt.Println("Multiplicação:", a*b) // 30
    fmt.Println("Divisão:", a/b)     // 3 (divisão inteira)
    fmt.Println("Módulo:", a%b)      // 1 (resto)

    // Incremento e decremento (somente como statements)
    a++  // a = a + 1
    b--  // b = b - 1
}
```

> **Nota**: Go não tem operadores de pré/pós-incremento como expressões (`++a` ou `--b` não retornam valores).

### Operadores de Comparação

```go
package main

import "fmt"

func main() {
    x, y := 5, 10

    fmt.Println("Igual:", x == y)      // false
    fmt.Println("Diferente:", x != y)  // true
    fmt.Println("Maior:", x > y)       // false
    fmt.Println("Menor:", x < y)       // true
    fmt.Println("Maior ou igual:", x >= y) // false
    fmt.Println("Menor ou igual:", x <= y) // true
}
```

## Funções

Funções são cidadãs de primeira classe em Go.

### Declaração Básica

```go
package main

import "fmt"

// Função simples
func saudar(nome string) {
    fmt.Printf("Olá, %s!\n", nome)
}

// Função com retorno
func somar(a, b int) int {
    return a + b
}

// Função com múltiplos parâmetros do mesmo tipo
func calcularArea(largura, altura float64) float64 {
    return largura * altura
}

func main() {
    saudar("Maria")
    resultado := somar(10, 20)
    area := calcularArea(5.0, 3.0)

    fmt.Println("Soma:", resultado)
    fmt.Println("Área:", area)
}
```

### Múltiplos Retornos

Uma característica poderosa de Go:

```go
package main

import "fmt"

// Retorna quociente e resto
func dividir(dividendo, divisor int) (int, int) {
    quociente := dividendo / divisor
    resto := dividendo % divisor
    return quociente, resto
}

// Retorna resultado e erro (padrão idiomático)
func dividirSeguro(dividendo, divisor float64) (float64, error) {
    if divisor == 0 {
        return 0, fmt.Errorf("divisão por zero")
    }
    return dividendo / divisor, nil
}

func main() {
    // Ignorando um retorno com _
    q, _ := dividir(17, 5)
    fmt.Println("Quociente:", q)

    q2, r := dividir(17, 5)
    fmt.Printf("%d dividido por %d = %d, resto %d\n", 17, 5, q2, r)

    // Tratando erro
    resultado, err := dividirSeguro(10.0, 0.0)
    if err != nil {
        fmt.Println("Erro:", err)
    } else {
        fmt.Println("Resultado:", resultado)
    }
}
```

### Named Return Values

Retornos nomeados tornam o código mais claro:

```go
package main

import "fmt"

// Retornos nomeados
func calcularStats(numeros []int) (min, max, media int) {
    if len(numeros) == 0 {
        return 0, 0, 0  // Retorna zero values
    }

    min = numeros[0]
    max = numeros[0]
    soma := 0

    for _, n := range numeros {
        if n < min {
            min = n
        }
        if n > max {
            max = n
        }
        soma += n
    }

    media = soma / len(numeros)
    return  // Retorna min, max, media automaticamente
}

func main() {
    nums := []int{5, 2, 8, 1, 9}
    minimo, maximo, media := calcularStats(nums)
    fmt.Printf("Min: %d, Max: %d, Média: %d\n", minimo, maximo, media)
}
```

### Funções Variádicas

Aceitam número variável de argumentos:

```go
package main

import "fmt"

// Função variádica
func somarTudo(numeros ...int) int {
    total := 0
    for _, n := range numeros {
        total += n
    }
    return total
}

func main() {
    fmt.Println(somarTudo(1, 2, 3))       // 6
    fmt.Println(somarTudo(10, 20))        // 30
    fmt.Println(somarTudo())              // 0

    // Passando slice com ...
    nums := []int{1, 2, 3, 4, 5}
    fmt.Println(somarTudo(nums...))       // 15
}
```

### Funções Anônimas e Closures

```go
package main

import "fmt"

func main() {
    // Função anônima atribuída a variável
    dobro := func(x int) int {
        return x * 2
    }

    fmt.Println(dobro(5))  // 10

    // Closure (função que captura variáveis do escopo)
    contador := func() func() int {
        count := 0
        return func() int {
            count++
            return count
        }
    }()

    fmt.Println(contador())  // 1
    fmt.Println(contador())  // 2
    fmt.Println(contador())  // 3
}
```

## Structs (Estruturas)

Structs agrupam campos relacionados:

### Declaração e Uso

```go
package main

import "fmt"

type Pessoa struct {
    Nome    string
    Idade   int
    Email   string
    Ativo   bool
}

func main() {
    // Criação de instância
    p1 := Pessoa{
        Nome:  "João Silva",
        Idade: 30,
        Email: "joao@exemplo.com",
        Ativo: true,
    }

    // Forma curta (ordem dos campos)
    p2 := Pessoa{"Maria Santos", 25, "maria@exemplo.com", true}

    // Struct parcial (campos omitidos ficam com zero value)
    p3 := Pessoa{
        Nome: "Pedro",
    }

    // Acesso aos campos
    fmt.Println("Nome:", p1.Nome)
    fmt.Println("Idade:", p1.Idade)

    // Modificação
    p1.Idade = 31
    fmt.Println("Nova idade:", p1.Idade)

    fmt.Printf("Pessoa 2: %+v\n", p2)
    fmt.Printf("Pessoa 3: %+v\n", p3)
}
```

### Structs Aninhados

```go
package main

import "fmt"

type Endereco struct {
    Rua     string
    Cidade  string
    Estado  string
    CEP     string
}

type Pessoa struct {
    Nome     string
    Idade    int
    Endereco Endereco  // Struct aninhado
}

func main() {
    pessoa := Pessoa{
        Nome:  "Ana Paula",
        Idade: 28,
        Endereco: Endereco{
            Rua:    "Av. Brasil, 123",
            Cidade: "São Paulo",
            Estado: "SP",
            CEP:    "01000-000",
        },
    }

    fmt.Printf("%s mora em %s, %s\n",
        pessoa.Nome,
        pessoa.Endereco.Cidade,
        pessoa.Endereco.Estado)
}
```

### Ponteiros para Structs

```go
package main

import "fmt"

type Pessoa struct {
    Nome  string
    Idade int
}

// Recebe ponteiro para modificar o original
func fazerAniversario(p *Pessoa) {
    p.Idade++  // Não precisa de (*p).Idade, Go faz automaticamente
}

func main() {
    p := Pessoa{"João", 30}

    fmt.Println("Antes:", p.Idade)  // 30

    fazerAniversario(&p)

    fmt.Println("Depois:", p.Idade)  // 31
}
```

## Métodos

Métodos são funções associadas a tipos (especialmente structs):

```go
package main

import "fmt"

type Retangulo struct {
    Largura  float64
    Altura   float64
}

// Método com receiver por valor (não modifica o original)
func (r Retangulo) Area() float64 {
    return r.Largura * r.Altura
}

// Método com receiver por ponteiro (pode modificar o original)
func (r *Retangulo) Escalar(fator float64) {
    r.Largura *= fator
    r.Altura *= fator
}

// Método com retorno formatado
func (r Retangulo) String() string {
    return fmt.Sprintf("Retângulo %.1f x %.1f", r.Largura, r.Altura)
}

func main() {
    ret := Retangulo{Largura: 10, Altura: 5}

    fmt.Println(ret.String())        // Retângulo 10.0 x 5.0
    fmt.Println("Área:", ret.Area()) // 50

    ret.Escalar(2)
    fmt.Println("Após escalar:", ret.String()) // Retângulo 20.0 x 10.0
}
```

### Quando Usar Ponteiro vs Valor?

| Use valor (r Retangulo) quando... | Use ponteiro (r *Retangulo) quando... |
|-----------------------------------|---------------------------------------|
| Não precisa modificar o receiver | Precisa modificar o receiver |
| Struct é pequena (copia é barata) | Struct é grande (evita cópia) |
| Thread safety é importante | Performance crítica |

## Type Conversion (Conversão de Tipos)

Go não faz conversão implícita — você deve converter explicitamente:

```go
package main

import "fmt"
import "strconv"

func main() {
    // Entre tipos numéricos
    var i int = 42
    var f float64 = float64(i)  // Conversão explícita obrigatória
    var u uint = uint(i)

    // String para número
    numStr := "123"
    num, _ := strconv.Atoi(numStr)  // string → int
    num64, _ := strconv.ParseInt(numStr, 10, 64)

    // Número para string
    str := strconv.Itoa(num)        // int → string
    strf := strconv.FormatFloat(3.14, 'f', 2, 64)

    // String para bytes e vice-versa
    texto := "Olá"
    bytes := []byte(texto)
    texto2 := string(bytes)

    fmt.Printf("int: %d, float64: %f, uint: %d\n", i, f, u)
    fmt.Printf("Número: %d, String: %s\n", num, str)
    fmt.Println(texto2)
}
```

## Exercícios Práticos

### Exercício 1: Calculadora de IMC

Crie uma função que calcula o IMC (Índice de Massa Corporal) dados peso e altura.

<details>
<summary>Ver solução</summary>

```go
package main

import "fmt"

func calcularIMC(peso, altura float64) float64 {
    return peso / (altura * altura)
}

func classificarIMC(imc float64) string {
    switch {
    case imc < 18.5:
        return "Abaixo do peso"
    case imc < 25:
        return "Peso normal"
    case imc < 30:
        return "Sobrepeso"
    default:
        return "Obesidade"
    }
}

func main() {
    peso := 70.0
    altura := 1.75

    imc := calcularIMC(peso, altura)
    classificacao := classificarIMC(imc)

    fmt.Printf("IMC: %.2f - %s\n", imc, classificacao)
}
```
</details>

### Exercício 2: Sistema de Biblioteca

Crie um sistema simples de biblioteca com struct `Livro` e métodos para emprestar e devolver.

<details>
<summary>Ver solução</summary>

```go
package main

import "fmt"

type Livro struct {
    Titulo    string
    Autor     string
    Emprestado bool
}

func (l *Livro) Emprestar() error {
    if l.Emprestado {
        return fmt.Errorf("livro já está emprestado")
    }
    l.Emprestado = true
    return nil
}

func (l *Livro) Devolver() error {
    if !l.Emprestado {
        return fmt.Errorf("livro não estava emprestado")
    }
    l.Emprestado = false
    return nil
}

func (l Livro) String() string {
    status := "Disponível"
    if l.Emprestado {
        status = "Emprestado"
    }
    return fmt.Sprintf("%s (por %s) - %s", l.Titulo, l.Autor, status)
}

func main() {
    livro := Livro{Titulo: "O Senhor dos Anéis", Autor: "J.R.R. Tolkien"}

    fmt.Println(livro)

    if err := livro.Emprestar(); err != nil {
        fmt.Println("Erro:", err)
    } else {
        fmt.Println("Livro emprestado com sucesso!")
    }

    fmt.Println(livro)
}
```
</details>

### Exercício 3: Gerenciador de Tarefas

Implemente um gerenciador de tarefas com structs e funções para adicionar, listar e completar tarefas.

<details>
<summary>Ver solução</summary>

```go
package main

import "fmt"
import "time"

type Tarefa struct {
    ID        int
    Titulo    string
    Completa  bool
    CriadaEm  time.Time
}

type GerenciadorTarefas struct {
    tarefas []Tarefa
    proxID  int
}

func (gt *GerenciadorTarefas) Adicionar(titulo string) Tarefa {
    tarefa := Tarefa{
        ID:       gt.proxID,
        Titulo:   titulo,
        Completa: false,
        CriadaEm: time.Now(),
    }
    gt.tarefas = append(gt.tarefas, tarefa)
    gt.proxID++
    return tarefa
}

func (gt *GerenciadorTarefas) Completar(id int) bool {
    for i := range gt.tarefas {
        if gt.tarefas[i].ID == id {
            gt.tarefas[i].Completa = true
            return true
        }
    }
    return false
}

func (gt GerenciadorTarefas) ListarPendentes() []Tarefa {
    var pendentes []Tarefa
    for _, t := range gt.tarefas {
        if !t.Completa {
            pendentes = append(pendentes, t)
        }
    }
    return pendentes
}

func main() {
    gt := GerenciadorTarefas{}

    gt.Adicionar("Estudar Go")
    gt.Adicionar("Fazer exercícios")
    gt.Adicionar("Ler documentação")

    gt.Completar(0)

    fmt.Println("Tarefas pendentes:")
    for _, t := range gt.ListarPendentes() {
        fmt.Printf("- %s\n", t.Titulo)
    }
}
```
</details>

## Dicas e Melhores Práticas

### 1. Nomenclatura

- Use `camelCase` para variáveis e funções privadas
- Use `PascalCase` para tipos, funções e variáveis exportadas
- Use `SCREAMING_SNAKE_CASE` para constantes

```go
const MAX_SIZE = 100  // Constante exportada
var contador = 0      // Variável privada
func calcular() {}    // Função privada
func Calcular() {}    // Função exportada (pública)
```

### 2. Zero Values são Seus Amigos

Aproveite que Go inicializa variáveis automaticamente:

```go
// Bom: aproveita zero values
var contador int  // Começa em 0
var encontrado bool // Começa em false

// Ruim: inicialização desnecessária
contador := 0
encontrado := false
```

### 3. Evite Variáveis Globais

Prefira passar dependências como parâmetros:

```go
// Ruim: variável global
var db *sql.DB

func main() {
    db = conectarDB()
}

// Bom: injeção de dependência
func main() {
    db := conectarDB()
    handler := NewHandler(db)
}
```

### 4. Trate Erros Explicitamente

Go não tem exceções — verifique erros:

```go
// Ruim: ignorando erro
file, _ := os.Open("dados.txt")

// Bom: tratando erro
file, err := os.Open("dados.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()
```

## Próximos Passos

Parabéns! Você domina agora os fundamentos da sintaxe de Go. Continue sua jornada:

### Próximo Artigo da Série

📖 **[Controle de Fluxo em Go: if, switch, loops →](./artigo-3-controle-de-fluxo)** — Aprenda a controlar o fluxo de execução com condicionais e loops.

### Recursos Recomendados

- 📋 [Go Cheatsheet](/cheatsheet/) — Referência rápida de toda a sintaxe
- 📚 [Effective Go](https://go.dev/doc/effective_go) — Guia de estilo oficial
- 🎓 [Go by Example](https://gobyexample.com/) — Mais exemplos práticos
- 💬 [Comunidade Golang Brasil](/comunidade) — Tire dúvidas

### Carreira Go

- 💰 [Salários Go no Brasil](/carreira/salarios-go-brasil/) — Quanto ganha um dev Go
- 💼 [Vagas Go](/vagas/) — Oportunidades atuais no mercado
- 🏢 [Empresas que usam Go](/empresas/) — 948+ empresas no Brasil

### Desafios

1. Crie uma calculadora completa com operações básicas
2. Implemente um jogo da forca em linha de comando
3. Crie um sistema de cadastro de produtos

---

*Artigo anterior: [Golang para Iniciantes: Primeiros Passos ←](./artigo-1-primeiros-passos)*  
*Próximo artigo: [Controle de Fluxo em Go: if, switch, loops →](./artigo-3-controle-de-fluxo)*

---

*Última atualização: 09 de fevereiro de 2026*  
*Versão do Go: 1.23*
