Estruturas básicas de controle com GO
O Go (ou golang) é uma linguagem criada em 2007 pela equipe de desenvolvimento do Google. Tinha como objetivo facilitar o desenvolvimento de sistemas sem a necessidade de se utilizar outras linguagens de programação.
Vamos ver neste artigo suas principais estruturas de controle, bem como a criação de funções.
O famoso olá mundo!
Normalmente, o primeiro exercício em uma linguagem desconhecida da gente é o "olá mundo". Apenas escrevemos código na nova linguagem que exibe essa mensagem.
Embora não pareça nada demais, é um indicativo de que o seu ambiente foi corretamente construído, para que você possa realmente aprender a nova ferramenta.
No caso do Go, é um pouco mais simples que outras linguagens, como Java por exemplo:
package main
import "fmt"
func main(){
fmt.Println("Olá mundo Go!")
}
Para rodarmos esse programa por linha de comando, não precisamos compilá-lo antes. Basta que salvemos esse código num arquivo .go
(olamundo.go, por exemplo):
$ go run olamundo.go
Olá mundo Go!
Declarar variáveis também é bem simples:
numero1 := 1
Nesse caso, estamos declarando uma variável chamada numero1, e atribuindo o valor 1 a ela. Note o operador de atribuição ( :=
).
Essa atribuição foi feita logo abaixo da mensagem inicial:
package main
import "fmt"
func main(){
fmt.Println("Olá mundo Go!")
numero1 := 1
}
Vamos então rodar esse programa...ops!
$ go run olamundo.go
# command-line-arguments
./olamundo.go:8:2: numero1 declared and not used
Repare que declaramos uma variável, mas esta não é usada em nenhuma parte do sistema, o que faz com que o interpretador go lance um erro de compilação. Esse recurso é bem interessante, pois disciplina o programador a manter somente o código que ele precisa. O time de criação da linguagem justifica a inclusão dessa característica no FAQ da linguagem. Basicamente:
The presence of an unused variable may indicate a bug, while unused imports just slow down compilation, an effect that can become substantial as a program accumulates code and programmers over time. For these reasons, Go refuses to compile programs with unused variables or imports, trading short-term convenience for long-term build speed and program clarity.
Logo, verificamos que eles se preocuparam não somente com variáveis que não são usadas, mas também com imports desnecessários, que podem fazer com que o processo de compilação fique mais lento. A explicação completa pode ser vista em https://golang.org/doc/faq#unused_variables_and_imports
Para que possamos remover esse erro, devemos dar uma finalidade a essa variável. No nosso caso, vamos apenas imprimir seu valor:
package main
import "fmt"
func main(){
fmt.Println("Olá mundo Go!")
numero1 := 1
fmt.Println(numero1)
}
E temos como saída:
$ go run olamundo.go
Olá mundo Go!
1
Nada muito inesperado, não é mesmo? Repare que, diferente de outras linguagens como Java por exemplo, a sintaxe é menos verbosa e burocrática. Não precisamos colocar ponto-e-vírgula no final de nossas instruções.
Podemos declarar outro número, e somarmos os 2, gerando um terceiro número:
package main
import "fmt"
func main(){
fmt.Println("Olá mundo Go!")
numero1 := 1
fmt.Println(numero1)
numero2 := 2
numero3 := numero1 + numero2
fmt.Println(numero3)
}
E se precisarmos comparar ambos os números, imprimindo quem é o maior? Teremos que comparar os números. Para isso, podemos usar instruções if/else e fazer as comparações:
if numero1 < numero2 {
fmt.Println("O número 1 é menor que o número 2")
} else if(numero1 == numero2){
fmt.Println("Os números 1 e 2 são iguais")
} else {
fmt.Println("O número 1 é maior que o número 2")
}
Repare que as instruções if podem ou não ter sua condicional entre parênteses. Normalmente elas são escritas sem os parênteses mesmo. Fiz aqui apenas para mostrar que é possível.
Podemos inclusive refatorar este código, de forma que tenhamos apenas uma instrução de impressão de mensagens para todos esses condicionais. Para isso, podemos declarar uma variável do tipo String:
var mensagem string
E atribuir valores a ela de acordo com as condicionais:
if numero1 < numero2 {
mensagem = "O número 1 é menor que o número 2"
} else if(numero1 == numero2) {
mensagem = "Os números 1 e 2 são iguais"
} else {
mensagem = "O número 1 é maior que o número 2"
}
fmt.Println(mensagem)
Há alguns pontos a se considerar. Diferente da maioria das linguagens, a declaração de variáveis do Go começa com a palavra chave var, seguida do nome da variável. Não há necessidade de declarar o tipo, embora possa ser necessário numa variável como essa, que pode ser usada em diversos pontos da função, garantindo que qualquer atribuição a ela seja do tipo declarado.
Além disso, note como a atribuição de valores à variável mensagem foi feita. Agora não usamos mais o operador :=
, mas apenas o =
. Para o Go, quando inicializamos uma variável com um determinado valor (o caso dos números por exemplo) usamos o primeiro operador. Nos demais, o segundo.
Mas, e se precisarmos verificar todos os números divisíveis por 5 entre 0 e 100, por exemplo? Para isso, podemos usar um looping, juntamente com o if:
for i := 0; i <= 50; i ++ {
if i % 5 == 0 {
fmt.Println(i, " é um número divisível por 5")
}
}
Repare que, assim como o if, o for também não precisa de parênteses. Esta característica, combinada com outras da linguagem, contribuem para tornar o código menos verboso.
Além disso, fizemos a concatenação entre o valor de i e uma string (com s minúsculo mesmo. Diferente de linguagens como Java por exemplo (e semelhante ao C#), string escreve-se com letra minúscula).
A saída desse código será:
$ go run olamundo.go
Olá mundo Go!
1
3
O número 1 é menor que o número 2
0 é um número divisível por 5
5 é um número divisível por 5
10 é um número divisível por 5
15 é um número divisível por 5
20 é um número divisível por 5
25 é um número divisível por 5
30 é um número divisível por 5
35 é um número divisível por 5
40 é um número divisível por 5
45 é um número divisível por 5
50 é um número divisível por 5
Agora que vimos as principais estruturas de controle em Go, vamos revisitar o código que já criamos:
package main
import "fmt"
func main(){
fmt.Println("Olá mundo Go!")
numero1 := 1
fmt.Println(numero1)
numero2 := 2
numero3 := numero1 + numero2
fmt.Println(numero3)
var mensagem string
if numero1 < numero2 {
mensagem = "O número 1 é menor que o número 2"
} else if(numero1 == numero2) {
mensagem = "Os números 1 e 2 são iguais"
} else {
mensagem = "O número 1 é maior que o número 2"
}
fmt.Println(mensagem)
for i := 0; i <= 50; i ++ {
if i % 5 == 0 {
fmt.Println(i, " é um número divisível por 5")
}
}
}
Temos código que lida com tarefas diferentes. Podemos organizá-lo em funções.
Comecemos com nosso primeiro cenário: a soma de 2 números:
numero1 := 1
fmt.Println(numero1)
numero2 := 2
fmt.Println(soma2numeros(numero1, numero2))
A função soma2numeros está abaixo:
func soma2numeros(n1, n2 int)
int {
return n1 + n2
}
Como os argumentos da função são do mesmo tipo, podemos simplificar a declaração de tipos, especificando-o apenas uma vez. Além disso, de forma semelhante à declaração de variáveis, colocamos o retorno da função no final de sua assinatura. Essa maneira de declarar tipos, seja de variáveis ou de funções, é algo a se destacar no Go, visto que a maioria das linguagens coloca a declaração de tipo antes da variável ou da função.
Podemos criar também uma função para encapsular a verificação de qual número é maior. Essa não retornará nada. Apenas exibirá no console quem é o maior número. O código dessa função está abaixo:
func qualEhOMaiorNumero(n1, n2 int){
var mensagem string
if n1 < n2 {
mensagem = "O número 1 é menor que o número 2"
} else if(n1 == n2) {
mensagem = "Os números 1 e 2 são iguais"
} else {
mensagem = "O número 1 é maior que o número 2"
}
fmt.Println(mensagem)
}
Como podemos ver, como ele não retorna nada, não colocamos nenhum tipo de retorno. Agora é só chamar a função no método main(), substituindo o código anterior por ela:
func main(){
fmt.Println("Olá mundo Go!")
numero1 := 1
fmt.Println(numero1)
numero2 := 2
fmt.Println(soma2numeros(numero1, numero2))
qualEhOMaiorNumero(numero1, numero2)
for i := 0; i <= 50; i ++ {
if i % 5 == 0 {
fmt.Println(i, " é um número divisível por 5")
}
}
}
Por último, vamos encapsular o código que verifica quais os números divisíveis por 5:
func numerosDivisiveisPor5Entre0e50(){
for i := 0; i <= 50; i ++ {
if i % 5 == 0 {
fmt.Println(i, " é um número divisível por 5")
}
}
}
E o nosso código final ficará assim:
package main
import "fmt"
func main(){
fmt.Println("Olá mundo Go!")
numero1 := 1
fmt.Println(numero1)
numero2 := 2
fmt.Println(soma2numeros(numero1, numero2))
qualEhOMaiorNumero(numero1, numero2)
numerosDivisiveisPor5Entre0e50()
}
func soma2numeros(n1, n2 int) int {
return n1 + n2
}
func qualEhOMaiorNumero(n1, n2 int){
var mensagem string
if n1 < n2 {
mensagem = "O número 1 é menor que o número 2"
} else if(n1 == n2) {
mensagem = "Os números 1 e 2 são iguais"
} else {
mensagem = "O número 1 é maior que o número 2"
}
fmt.Println(mensagem)
}
func numerosDivisiveisPor5Entre0e50(){
for i := 0; i <= 50; i ++ {
if i % 5 == 0 {
fmt.Println(i, " é um número divisível por 5")
}
}
}
Considerações finais
Vimos como criar estruturas básicas de controle em Go, tais como declaração de variáveis, if/else, loopings e funções. Com esses recursos, é possível a criação de programas simples em Go.
Entretanto, caso queira saber mais, há o livro Programando em Go, do Caio Filipini, disponível na Casa do Código.
E aqui na Alura temos alguns curso para iniciar sua carreira em GO.
Bons estudos e até a próxima!