Sintaxe Básica
A sintaxe básica do Go é muito simples e fácil de entender, vamos começar com um exemplo bem simples.
package main
import "fmt"
func main() {
fmt.Println("Hello 世界!")
}A palavra-chave
packagedeclara a qual pacote o arquivo go atual pertence, o arquivo de entrada deve ser declarado como pacotemain, a função de entrada é a funçãomain, 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çãoPrintlndo pacotefmtpara 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.
package example
// Público
const MyName = "jack"
// Privado
const mySalary = 20_000Esta 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
package main
import "example"Ao importar múltiplos pacotes, você pode escrever assim
package main
import "example"
import "example1"Também pode usar parênteses para agrupar, o método abaixo é mais comum na prática.
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
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.
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.
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.
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.goPela 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
// 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
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return varOperadores
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.
a += 1
a /= 2
a &^= 2TIP
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-- // corretoOutro 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.
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 // 0Literal de Ponto Flutuante
Através de diferentes prefixos pode-se expressar números de ponto flutuante em diferentes bases
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
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.25iLiteral de Caractere
O literal de caractere deve ser envolvido por aspas simples '', os caracteres em Go são totalmente compatíveis com utf8.
'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)
`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
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
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
// Exemplo correto
func main() {
fmt.Println("Hello 世界!")
}Se você realmente fizer isso, como abaixo
// 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*2Como 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
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
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
var c = a > b ? a : bAtravés deste artigo você pode ter uma compreensão preliminar da sintaxe do Go, os conteúdos seguintes serão expandidos com mais detalhes.
