Características notáveis da sintaxe
Ponto-e-vírgula
O ponto-e-vírgula ;
é usado não para terminar expressões, mas para separá-las. Outra curiosa característica é que ele pode ser omitido quando a linha de código termina com algo que sugira o fim de uma linha. Sua função é semelhante a na linguagem Ruby, ou seja, quase ausente. Pense assim: ele só é necessário para separar duas (ou mais) expressões que aparecem numa mesma linha [ou em declarações espefícicas como no for
].
//...
exp1; exp2; exp3
exp4
exp5
exp6
//...
Palavras-chave package e import
A palavra-chave package
serve para indicar [e isso é obrigatório] de que pacote o presente arquivo código-fonte é parte [o padrão é main
]. Já a palavra-chave import
serve, obviamente, para importar outros pacotes para o programa.
package main
import "fmt"
//...
Repare nessas três outras maneiras de se importar um pacote:
package main
import(
"fmt"
)
func main() { fmt.Printf("H.A.L.: Good Morning, Dave\n") }
package main
import(
. "fmt"
)
func main() { Printf("UT bot: Faster, stronger, better!\n") }
Usando-se o ponto antes do nome do pacote, ele é importado diretamente. Assim você pode usar um método sem ter de precedê-lo pelo nome do pacote.
package main
import(
X "fmt"
)
func main() { X.Printf("H.A.L.: Good Morning, Dave\n") }
Usando-se o qualquer prefixo antes do nome do pacote, ele é associado ao pacote (apenas nesse arquivo código-fonte). Assim você pode usar um método precedendo-o pelo prefixo que quiser. Isso também evita problemas ao se importar diferentes pacotes com o mesmo nome.
Comentários
São no estilo C++:
/* uma ou
mais linhas */
// uma linha, apenas
Estrutura de um programa Go
Forma mínima
package main
import "pkg1"
func main() {
// código
}
Forma mais complexa
package main
import (
"pkg1"
"pkg2"
"./mypkg"
)
var umaVar = 'Go é bacana'
var (
v1 = 1
v2 = 2.0
v3 = "3"
)
const Z = "qq coisa"
const (
Const1 = 123
Const2 = "abc"
)
func funcQualquer() {
// código
}
func main() {
// código
}
Compilando o programa
A compilação de programa em Go é feita em duas etapas [salvo quando usa-se gccgo]: a compilação em si e a linkagem com o sistema. Além disso, há diferenças se você estiver compilando para um sistema de 32 ou 64 bit.
Uma maneira simples de memorizar qual programa é usado em cada caso é considerar que o nome consiste sempre em um númeral seguido de uma letra, sendo que o númeral é uma referência à arquitetura e a letra ao tipo de processo (g: compilação Go, l: linkagem).
Os programas são:
6g, 6l, 8g, 8l
O que começam por '8', referem-se à arquiterura de 32bit (x86, 386), os que começam por '6', referem-se à 64bit (x86_64, amd64) [há também uma terceira, ARM, cujos programas são 5g e 5l, sabem, os deuses, o porquê].
Para evitar confusão, nesse tutorial usaremos sempre 6g e 6l. Entenda-se, porém, o correspondente à sua arquitetura. Ah, um detalhe, você vai usar o programa relativo à arquitetura de onde Go está/será instalado, não aquela para a qual você compilará o programa. Em tese, 6g e 6l compilarão para 32 e 64 bit a depender da variável $GOARCH que poderá ser alterada a qualquer instante antes da compilação. Abra o terminal, siga até a pasta onde o arquivo teste.go se encontra [por exemplo, cd ~/Desktop
] e, finalmente, digite os seguinte comandos.
# compilando o programa teste.go
6g teste.go #=> gera o arquivo teste.6
6l teste.6 #=> gera o arquivo teste.out
# Você pode, nesse segundo passo, compilar assim:
# 6l -o teste teste.6
# O resultado será o arquivo: teste
Compile o seguinte arquivo para testar. Salve com extensão .go
Obs: A quebra de linha ao final do documento é obrigatória.
// teste.go
package main
import "fmt"
func main() {
fmt.Printf("Go é um super C!\n")
}
Exemplos para você brincar
Não se preocupe em entender tudo agora...
package main
import "fmt"
func main() {
// Variável "alguém" de valor "Mundo"
// (sim, com acento e tudo, rsrs)
alguém := "Mundo"
// Imprimindo uma parte por vez...
fmt.Printf("Olá ")
fmt.Printf(alguém) // conteúdo da variável "alguém"
fmt.Printf("\n")
// numa mesma linha
fmt.Printf("Olá "); fmt.Printf(alguém); fmt.Printf("\n")
// ou inserindo uma string na outra como em C
fmt.Printf("Olá %s\n",alguém)
/* O resultado será o mesmo nos 3 casos:
Olá Mundo
Olá Mundo
Olá Mundo
*/
}
package main
import "fmt"
func main() {
//Veja, eu sei contar...
fmt.Printf("\nVeja, eu sei contar...\n\n")
for i := 1; i <= 10; i++ {
fmt.Printf("%d\n",i)
}
//Agora ao contrário...
fmt.Printf("\nAgora ao contrário...\n\n")
for i := 10; i >= 1; i-- {
fmt.Printf("%d\n",i)
}
//De 2 em 2...
fmt.Printf("\nDe 2 em 2...\n\n")
for i := 2; i <= 10; i+=2 {
fmt.Printf("%d\n",i)
}
//De 3 em 3 ao contrário...
fmt.Printf("\nDe 3 em 3 ao contrário...\n\n")
for i := 12; i >= 1; i-=3 {
fmt.Printf("%d\n",i)
}
}
package main
import "fmt"
func main() {
// Quais números são mostrados?
for i := 0;; i++ {
if i > 3 && i <= 5 || i%2 != 0 { continue }
if i > 16 { break }
fmt.Printf("%d\n",i)
}
}
package main
import "fmt"
func main() {
x := "abc"
for { // É um "loop" puro
fmt.Printf("%s\n",x)
switch x {
case "abc": x += " def"; continue
case "abc def": x += " ghi"; continue
case "abc def ghi": x += " jkl"; continue
// "continue" refere-se ao "for", não é parte do "switch"
}
break
}
/*
Resultado:
abc
abc def
abc def ghi
abc def ghi jkl
*/
}
package main
import "fmt"
func duploRetorno() (int, int) {
return 1, 2
}
func main() {
x, y := duploRetorno()
fmt.Printf("%d\n",x)
fmt.Printf("%d\n",y)
/*
Resultado:
1
2
*/
}