Skip to content

Sintaxe Básica

A sintaxe básica do Go é muito simples e fácil de entender, vamos começar com um exemplo bem simples.

go
package main

import "fmt"

func main() {
   fmt.Println("Hello 世界!")
}
  • A palavra-chave package declara a qual pacote o arquivo go atual pertence, o arquivo de entrada deve ser declarado como pacote main, a função de entrada é a função main, ao criar pacotes e funções personalizadas deve-se evitar nomes que entrem em conflito com eles.

  • import é a palavra-chave de importação, seguida pelo nome do pacote a ser importado.

  • func é a palavra-chave de declaração de função, usada para declarar uma função.

  • fmt.Println("Hello 世界!") é uma instrução que chama a função Println do pacote fmt para realizar a saída.

Acima está uma introdução simples à sintaxe, a seguir vamos entender com mais detalhes os conceitos envolvidos.

Pacotes

Em Go, os programas são construídos através da vinculação de pacotes. A unidade básica de importação em Go é um pacote, não um arquivo .go. Um pacote é na verdade uma pasta, em inglês package, todas as variáveis, constantes e todos os tipos definidos são compartilhados dentro do pacote. O estilo de nomenclatura de pacotes recomenda que sejam todas letras minúsculas e o mais curtas possível.

Visibilidade

Mencionamos anteriormente que todas as variáveis, constantes e todos os tipos definidos são compartilhados dentro do pacote, mas para fora do pacote não é assim, às vezes você não quer que outros acessem um determinado tipo, então precisa controlar a visibilidade. Você pode ter visto palavras-chave como Public, Private em outras linguagens OOP, mas em Go não existem essas palavras, a forma de controlar a visibilidade é muito simples, as regras são as seguintes

  • Nome começando com letra maiúscula é um tipo/variável/constante público
  • Nome começando com letra minúscula ou sublinhado é um tipo/variável/constante privado

Por exemplo, no exemplo abaixo, a constante MyName é pública, enquanto a constante mySalary é privada.

go
package example

// Público
const MyName = "jack"

// Privado
const mySalary = 20_000

Esta regra de visibilidade se aplica a qualquer lugar em Go.

Importação

Importe um pacote para usar os tipos/métodos/funções/variáveis desse pacote, a sintaxe de importação é import seguido do nome do pacote

go
package main

import "example"

Ao importar múltiplos pacotes, você pode escrever assim

go
package main

import "example"
import "example1"

Também pode usar parênteses para agrupar, o método abaixo é mais comum na prática.

go
package main

import (
  "example"
  "example1"
)

Se houver nomes de pacotes duplicados, ou se o nome do pacote for complexo, você também pode dar apelidos a eles

go
package main

import (
  e "example"
  e1 "example1"
)

Quando o alias é sublinhado _ é uma importação anônima, pacotes importados anonimamente não podem ser usados, isso geralmente é feito para carregar a função init do pacote, mas sem precisar usar os tipos do pacote, um exemplo comum é registrar drivers de banco de dados, mas você não precisa usar o driver manualmente.

go
package main

import (
  e "example"
  _ "mysql-driver-go"
)

Após importar, quando quiser acessar os tipos do pacote, use nomeDoPacote.identificador para acessar, como no exemplo abaixo, se você tentar acessar um tipo privado, o compilador informará que não é possível acessar.

go
package main

import (
  "example"
   "fmt"
)

func main() {
    fmt.Println(example.MyName)
}

Existe uma forma especial de importação que importa todos os tipos do pacote para o escopo do pacote atual, tipos importados desta forma não precisam mais do operador . para acessar, mas se houver tipos com o mesmo nome não será possível compilar.

go
package main

import (
  . "example"
)

WARNING

Em Go não é possível fazer importação circular, seja direta ou indireta. Por exemplo, o pacote A importa o pacote B, e o pacote B também importa o pacote A, isso é importação circular direta. Se o pacote A importa o pacote C, o pacote C importa o pacote B, e o pacote B importa o pacote A, isso é importação circular indireta. Se houver importação circular, não será possível compilar.

Pacote Interno

Em Go, é convenção que um pacote chamado internal dentro de um pacote é um pacote interno, pacotes externos não poderão acessar nenhum conteúdo do pacote interno, caso contrário a compilação não passará, veja um exemplo abaixo.

/home/user/go/
    src/
        crash/
            bang/              (go code in package bang)
                b.go
        foo/                   (go code in package foo)
            f.go
            bar/               (go code in package bar)
                x.go
            internal/
                baz/           (go code in package baz)
                    z.go
            quux/              (go code in package main)
                y.go

Pela estrutura de arquivos, sabe-se que o pacote crash não pode acessar os tipos do pacote baz.

Comentários

Go suporta comentários de linha única e comentários de múltiplas linhas, recomenda-se deixar um espaço entre o comentário e o conteúdo, por exemplo

go
// Este é o pacote main
package main

// Importou o pacote fmt
import "fmt"

/*
*
Esta é a função de inicialização main
*/
func main() {
  // Esta é uma instrução
  fmt.Println("Hello 世界!")
}

Identificadores

Um identificador é um nome, usado para nomear pacotes, funções, variáveis, etc., as regras de nomenclatura são as seguintes

  • Só pode ser composto por letras, números e sublinhados
  • Só pode começar com letra ou sublinhado
  • Diferencia estritamente maiúsculas de minúsculas
  • Não pode entrar em conflito com nenhum identificador existente, ou seja, deve ser único dentro do pacote
  • Não pode entrar em conflito com nenhuma palavra-chave incorporada do Go

Abaixo estão listadas todas as palavras-chave incorporadas, também pode ir para Manual de Referência - Identificadores para ver mais detalhes

go
break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

Operadores

Abaixo está a ordem de precedência dos operadores suportados em Go, também pode ir para Manual de Referência - Operadores para ver mais detalhes.

Precedence    Operator
    5             *  /  %  <<  >>  &  &^
    4             +  -  |  ^
    3             ==  !=  <  <=  >  >=
    2             &&
    1             ||

Um ponto que merece atenção, Go não escolheu usar ~ como operador de inversão de bits, em vez disso reutilizou o símbolo ^. Quando dois números usam ^, por exemplo a^b, ele é o operador XOR, quando usado apenas em um número, por exemplo ^a, então ele é o operador de inversão de bits. Go também suporta operadores de atribuição aumentada, como abaixo.

go
a += 1
a /= 2
a &^= 2

TIP

Em Go não existem operadores de incremento e decremento, eles foram rebaixados para declarações statement, e é estabelecido que só podem estar após o operando, então não precisa mais se preocupar com questões como i++ e ++i.

a++ // correto
++a // errado
a-- // correto

Outro ponto é que eles não têm mais valor de retorno, portanto instruções como a = b++ estão erradas.

Literais

Literais, em termos de ciência da computação, são símbolos usados para expressar um valor fixo no código fonte, também chamados de valores literais. Os dois nomes significam a mesma coisa, o que for escrito, o valor será isso, o valor é "literalmente" o valor.

Literal de Inteiro

Para facilitar a leitura, é permitido usar o sublinhado _ para separar dígitos, mas só é permitido usar após o prefixo e entre os dígitos.

go
24 // 24
024 // 24
2_4 // 24
0_2_4 // 24
10_000 // 10k
100_000 // 100k
0O24 // 20
0b00 // 0
0x00 // 0
0x0_0 // 0

Literal de Ponto Flutuante

Através de diferentes prefixos pode-se expressar números de ponto flutuante em diferentes bases

go
0.
72.40
072.40       // == 72.40
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5
1_5.         // == 15.0
0.15e+0_2    // == 15.0

0x1p-2       // == 0.25
0x2.p10      // == 2048.0
0x1.Fp+0     // == 1.9375
0X.8p-0      // == 0.5
0X_1FFFP-16  // == 0.1249847412109375
0x15e-2      // == 0x15e - 2 (integer subtraction)

Literal de Número Complexo

go
0i
0123i         // == 123i
0o123i        // == 0o123 * 1i == 83i
0xabci        // == 0xabc * 1i == 2748i
0.i
2.71828i
1.e+0i
6.67428e-11i
1E6i
.25i
.12345E+5i
0x1p-2i       // == 0x1p-2 * 1i == 0.25i

Literal de Caractere

O literal de caractere deve ser envolvido por aspas simples '', os caracteres em Go são totalmente compatíveis com utf8.

go
'a'
'ä'
''
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'

Caracteres de Escape

Caracteres de escape disponíveis em Go

\a   U+0007 caractere de sino
\b   U+0008 caractere de backspace
\f   U+000C caractere de form feed
\n   U+000A caractere de nova linha
\r   U+000D caractere de carriage return
\t   U+0009 caractere de tabulação horizontal
\v   U+000B caractere de tabulação vertical
\\   U+005C escape de barra invertida
\'   U+0027 escape de aspas simples (válido apenas dentro de caracteres)
\"   U+0022 escape de aspas duplas (válido apenas dentro de strings)

Literal de String

O literal de string deve ser envolvido por aspas duplas "" ou crases `` (strings com crases não permitem escape)

go
`abc`                // "abc"
`\n
\n`                  // "\\n\n\\n"
"\n"
"\""                 // `"`
"Hello, world!\n"
"今天天气不错"
"日本語"
"\u65e5\U00008a9e"
"\xff\u00FF"

Funções

A forma de declarar funções em Go é através da palavra-chave func, semelhante à maioria das linguagens

go
func main() {
  println(1)
}

No entanto, as funções em Go têm dois pontos diferentes, o primeiro é que o tipo do parâmetro vem depois, assim

func Hello(name string) {
  fmt.Println(name)
}

O segundo ponto diferente é que pode ter múltiplos valores de retorno, e pode ter nomes

go
func Pos() () (x, y float64) {
    ...
}

Estilo

Quanto ao estilo de codificação, Go força todos a usar o mesmo estilo. Go fornece oficialmente uma ferramenta de formatação gofmt, que pode ser usada via linha de comando. Esta ferramenta de formatação não tem nenhum parâmetro de formatação que possa ser passado, os dois únicos parâmetros são apenas para saída do processo de formatação, então não suporta personalização, ou seja, todo código formatado por esta ferramenta terá o mesmo estilo de código, isso reduzirá muito a carga mental dos mantenedores, então buscar individualidade nesta área não é uma escolha muito sábia.

Abaixo serão listadas algumas regras simples, que você também pode observar um pouco ao escrever código.

Quebra de Linha de Chaves de Função

Sobre se as chaves após uma função devem ou não quebrar linha, quase todo programador pode dar sua própria razão. Em Go, todas as chaves não devem quebrar linha

go
// Exemplo correto
func main() {
  fmt.Println("Hello 世界!")
}

Se você realmente fizer isso, como abaixo

go
// Exemplo errado
func main()
{
  fmt.Println("Hello 世界!")
}

Esse código nem sequer compila, então Go força todos os programadores a não quebrarem linha após as chaves de função.

Indentação de Código

Go usa por padrão Tab, ou seja, caracteres de tabulação para indentação, apenas em alguns casos especiais usa espaços.

Espaçamento de Código

A maior parte do espaçamento em Go tem significado, até certo ponto, isso também representa como o compilador vê seu código, por exemplo, a operação matemática abaixo

2*9 + 1/3*2

Como todos sabem, a multiplicação tem precedência maior que a adição, após a formatação, o espaçamento entre os símbolos * parecerá mais compacto, significando que a operação tem prioridade, enquanto o espaçamento ao redor do símbolo + é maior, representando que a operação vem depois.

Omissão de Chaves

Em outras linguagens, as instruções if e for geralmente podem ser abreviadas, assim

c
for (int i=0; i < 10; i++) printf("%d", i)

Mas em Go não, você pode escrever apenas uma linha, mas deve adicionar as chaves

go
for i := 0; i < 10; i++ {fmt.Println(i)}

Expressão Ternária

Go não tem expressão ternária, então código como o abaixo não pode compilar

go
var c = a > b ? a : b

Através deste artigo você pode ter uma compreensão preliminar da sintaxe do Go, os conteúdos seguintes serão expandidos com mais detalhes.

Golang por www.golangdev.cn edit