As variáveis são um importante conceito de programação a dominar. Tratam-se de símbolos que assumem um valor que você está usando em um programa.
Este tutorial abordará alguns princípios básicos sobre as variáveis e melhores práticas para usá-las dentro dos programas em Go que você criar.
Em termos técnicos, uma variável está atribuindo um local de armazenamento a um valor que é associado a um nome simbólico ou identificador. Usamos o nome da variável para referenciar aquele valor armazenado em de um programa de computador.
Podemos pensar em uma variável como um rótulo que tem um nome nele, o qual você vincula a um valor.
Vamos supor que temos um número inteiro, 1032049348
e queremos armazená-lo em uma variável em vez de ter que digitar esse número por repetidas vezes. Para alcançar isso, podemos usar um nome que seja fácil de lembrar, como a variável i
. Para armazenar um valor em uma variável, usamos a seguinte sintaxe:
i := 1032049348
Podemos pensar nessa variável como um rótulo que está ligado ao valor.
O rótulo tem o nome da variável i
escrito nele, e está ligado ao valor inteiro 1032049348
.
A frase i := 1032049348
é uma instrução de declaração e de atribuição que consiste em algumas partes:
i
):=
)1032049348
)int
)Mais adiante, na próxima seção, veremos como definir o tipo de maneira explícita.
Juntas, essas partes compõem a instrução que define a variável i
como sendo igual ao valor do inteiro 1032049348
.
Assim que definimos uma variável como sendo igual a um valor, inicializamos ou criamos essa variável. Feito isso, estamos prontos para usar a variável em vez do valor.
Assim que definirmos i
como sendo igual ao valor 1032049348
, poderemos usar i
no lugar do número inteiro, então, vamos imprimi-la:
package main
import "fmt"
func main() {
i := 1032049348
fmt.Println(i)
}
Output1032049348
Também podemos usar as variáveis para fazer operações matemáticas de maneira rápida e fácil. Com i := 1032049348
, podemos subtrair o valor inteiro 813
com a seguinte sintaxe:
fmt.Println(i - 813)
Output1032048535
Neste exemplo, a linguagem Go faz a operação para nós, subtraindo 813 da variável i
para retornar a soma 1032048535
.
A propósito da matemática, as variáveis podem ser definidas como sendo iguais aos resultados de uma equação matemática. Também podemos adicionar dois números juntos e armazenar o valor da soma na variável x
:
x := 76 + 145
Você deve ter notado que esse exemplo se parece com álgebra. Da mesma forma que usamos letras e outros símbolos para representar números e quantidades em fórmulas e equações, as variáveis são nomes simbólicos que representam o valor de um tipo de dados. Para garantir o uso correto da sintaxe em Go, você precisará garantir que a sua variável esteja do lado esquerdo de qualquer equação.
Vamos seguir em frente e imprimir x
:
package main
import "fmt"
func main() {
x := 76 + 145
fmt.Println(x)
}
Output221
A linguagem Go retornou o valor 221
porque a variável x
foi definida como sendo igual à soma de 76
e 145
.
As variáveis podem representar qualquer tipo de dados, não apenas os inteiros:
s := "Hello, World!"
f := 45.06
b := 5 > 9 // A Boolean value will return either true or false
array := [4]string{"item_1", "item_2", "item_3", "item_4"}
slice := []string{"one", "two", "three"}
m := map[string]string{"letter": "g", "number": "seven", "symbol": "&"}
Se imprimir qualquer uma dessas variáveis, Go retornará o que for equivalente a essa variável. Vamos trabalhar com a instrução de atribuição para o tipo de dados slice
da string:
package main
import "fmt"
func main() {
slice := []string{"one", "two", "three"}
fmt.Println(slice)
}
Output[one two three]
Atribuímos o valor da fatia da []string{"one", "two", "three"}
para a slice
da variável e, em seguida, usamos a função fmt.Println
para imprimir aquele valor, chamando a slice
.
As variáveis funcionam criando uma pequena área na memória do seu computador - que aceita valores especificados que são, na sequência, associados com aquele espaço.
Em Go, existem diversas maneiras de declarar uma variável e, em alguns casos, mais de uma forma de declarar a mesma variável e valor.
Podemos declarar uma variável chamada i
de dados do tipo int
sem inicialização. Isso significa que vamos declarar um espaço para colocar um valor, mas não dar a ele um valor inicial:
var i int
Isso cria uma variável declarada como i
de dados do tipo int
.
Podemos inicializar o valor, usando o operador igual (=)
, assim como no exemplo a seguir:
var i int = 1
Em Go, ambas as formas de declaração são chamadas declarações longas de variáveis.
Também podemos usar uma declaração curta de variável:
i := 1
Neste caso, temos uma variável chamada i
e um tipo de dados int
. Quando não especificarmos um tipo de dados, a Go irá inferir o tipo de dado.
Com as três maneiras de declarar as variáveis, a comunidade Go adotou as seguintes expressões:
Use apenas a forma longa, var i int
, quando não estiver inicializando a variável.
Use a forma curta, i :=1
, ao declarar e inicializar.
Se não quiser que a Go infira o seu tipo de dados, mas ainda quiser usar uma declaração de variável curta, é possível encapsular seu valor no seu tipo desejado, com a seguinte sintaxe:
i := int64(1)
O uso da forma longa de declaração de variáveis não é considerado natural na linguagem Go, quando estamos inicializando o valor:
var i int = 1
É uma boa prática seguir a maneira como a comunidade Go normalmente declara as variáveis para que outros possam ler seus programas sem problemas.
Todos os tipos integrados têm um valor zero. Qualquer variável alocada é utilizável, mesmo se nunca tiver tido um valor atribuído. Podemos ver os valores zero com os seguintes tipos:
package main
import "fmt"
func main() {
var a int
var b string
var c float64
var d bool
fmt.Printf("var a %T = %+v\n", a, a)
fmt.Printf("var b %T = %q\n", b, b)
fmt.Printf("var c %T = %+v\n", c, c)
fmt.Printf("var d %T = %+v\n\n", d, d)
}
Outputvar a int = 0
var b string = ""
var c float64 = 0
var d bool = false
Usamos o verbo %T
na instrução fmt.Printf
. Isso diz à função para imprimir o data type
da variável.
Em Go, como todos os valores têm um valor zero
, não podemos ter valores undefined
[não definidos] como em algumas outras linguagens. Por exemplo, um boolean
em algumas linguagens poderia ser undefined
, true
, ou false
, o que permite three
estados para a variável. Em Go, não podemos ter mais de two
estados de um valor booleano.
A nomeação de variáveis é bastante flexível, mas existem algumas regras a serem lembradas:
_
).Seguindo essas regras, vejamos alguns exemplos de nomes de variáveis válidos e inválidos:
Válidos | Inválidos | Por que inválidos |
---|---|---|
userName |
user-name |
Hifens não são permitidos |
name4 |
4name |
Não é possível começar com um número |
user |
$user |
Não é possível usar símbolos |
userName |
user name |
Não é possível haver mais de uma palavra |
Além disso, ao nomear as variáveis, tenha em mente que elas diferenciam letras maiúsculas de minúsculas. Estes nomes userName
, USERNAME
, UserName
e uSERnAME
são todos de variáveis completamente diferentes. Como parte das melhores práticas, é melhor evitar o uso de nomes de variáveis semelhantes dentro de um programa, a fim de garantir que você e seus colaboradores — atuais e futuros — consigam ter clareza quanto às suas variáveis.
Embora as variáveis diferenciem letras maiúsculas de minúsculas, a caixa (alta ou baixa) em que vem a primeira letra de uma variável tem um significado especial em Go. Se uma variável iniciar com uma letra em caixa alta, então essa variável é acessível fora do pacote em que foi declarada (ou exported
[exportada]). Se uma variável iniciar com uma letra em caixa baixa, então ela está disponível apenas dentro do pacote em que foi declarada.
var Email string
var password string
Email
começa com uma letra em caixa alta e pode ser acessada por outros pacotes. password
começa com uma letra minúscula e é acessível apenas dentro do pacote em que ela foi declarada.
É comum usar nomes de variáveis bastante concisos (ou curtos) em Go. Frente às opções de escolha entre userName
e user
para uma variável, a escolha mais natural seria user
.
O escopo também desempenha um papel na concisão do nome da variável. A regra é que, quanto menor o escopo em que a variável existe, menor o nome da variável:
names := []string{"Mary", "John", "Bob", "Anna"}
for i, n := range names {
fmt.Printf("index: %d = %q\n", i, n)
}
Usamos a variável names
em um escopo mais amplo. Dessa forma, seria comum dar a ela um nome mais significativo para ajudar a lembrar o que ela significa no programa. No entanto, usamos as variáveis i
e n
imediatamente na linha seguinte do código e, depois, não as usamos novamente. Por isso, a pessoa que estiver lendo o código não irá confundir-se quanto a onde as variáveis são usadas, ou o que significam.
A seguir, vamos tratar de algumas observações a respeito do estilo da variável. O estilo consiste em usar MixedCaps
(letras em caixas mistas) ou mixedCaps
, em vez de usar sublinhados para nomes com várias palavras.
Estilo convencional | Estilo não convencional | Por que não convencional |
---|---|---|
userName |
user_name |
Sublinhados não são convencionais |
i |
index |
prefira i a index por ser mais curto |
serveHttp |
serveHttp |
os acrônimos devem ser em letras maiúsculas |
O mais importante na questão de estilo é a consistência, bem como que a equipe com quem trabalha concorde com o estilo.
Assim como a palavra “variável” indica, podemos alterar as variáveis do Go facilmente. Isso significa que podemos conectar um valor diferente com uma variável previamente atribuída através de uma reatribuição. Essa capacidade de reatribuir é útil porque, ao longo de um programa, podemos precisar aceitar valores gerados pelo usuário em variáveis já inicializadas. Também podemos precisar alterar a atribuição para algo definido anteriormente.
Saber que podemos reatribuir uma variável facilmente pode ser útil ao trabalhar em um programa grande que outra pessoa escreveu, onde não está claro quais variáveis já foram definidas.
Vamos atribuir o valor 76
a uma variável chamada i
do tipo int
e, então, atribuir a ela um novo valor de 42
:
package main
import "fmt"
func main() {
i := 76
fmt.Println(i)
i = 42
fmt.Println(i)
}
Output76
42
Esse exemplo mostra que podemos atribuir primeiro a variável i
com o valor de um número inteiro e, em seguida, reatribuir a variável i
, atribuindo-lhe desta vez o valor 42
.
Nota: quando declarar e inicializar uma variável, você pode utilizar :=
; no entanto, quando quiser simplesmente alterar o valor de uma variável já declarada, basta usar o operador igual (=
).
Como Go é uma linguagem typed
, não é possível atribuir um tipo a outro. Por exemplo, não podemos atribuir o valor "Sammy"
a uma variável do tipo int
:
i := 72
i = "Sammy"
Tentar atribuir diferentes tipos entre si resultará em um erro de tempo de compilação:
Outputcannot use "Sammy" (type string) as type int in assignment
A linguagem Go não nos permitirá usar um nome de variável mais de uma vez:
var s string
var s string
Outputs redeclared in this block
Se tentarmos usar uma declaração de variável curta mais de uma vez para o mesmo nome da variável, também receberemos um erro de compilação. Isso pode acontecer por engano, de modo que é útil entender o que a mensagem de erro significa:
i := 5
i := 10
Outputno new variables on left side of :=
Assim como acontece com a declaração de uma variável, repensar os nomes de suas variáveis melhorará a legibilidade do seu programa para você e outros, quando revisitá-lo no futuro.
A linguagem Go também nos permite atribuir vários valores a várias variáveis na mesma linha. Cada um desses valores pode ser de um tipo de dados diferente:
j, k, l := "shark", 2.05, 15
fmt.Println(j)
fmt.Println(k)
fmt.Println(l)
Outputshark
2.05
15
Neste exemplo, a variável j
foi atribuída para a string "shark"
, a variável k
foi atribuída para o número de float 2.05
e a variável l
foi atribuída para o número inteiro 15
.
Com essa abordagem de atribuir várias variáveis a vários valores em uma linha, você conseguirá manter um número baixo de linhas no seu código. No entanto, é importante não comprometer a legibilidade apenas para reduzir o número de linhas do código.
Ao usar variáveis dentro de um programa, é importante ter o escopo da variável em mente. O escopo de uma variável se refere aos lugares em que ela fica acessível dentro do código de um dado programa. Isso significa que nem todas as variáveis são acessíveis de todas as partes de um dado programa — algumas variáveis serão globais e algumas serão locais.
As variáveis globais existem fora de funções. As variáveis locais existem dentro de funções.
Vejamos as variáveis globais e locais em ação:
package main
import "fmt"
var g = "global"
func printLocal() {
l := "local"
fmt.Println(l)
}
func main() {
printLocal()
fmt.Println(g)
}
Outputlocal
global
Aqui, usamos o var g = "global"
para criar uma variável global fora da função. Então, definimos a função printLocal()
. Dentro da função, uma variável local chamada l
é atribuída e, depois, impressa. O programa termina chamando o printLocal()
na, na sequência, imprimindo a variável global g
.
Como o g
é uma variável global, podemos referir-nos a ela em printLocal()
. Vamos modificar o programa anterior para fazer isso:
package main
import "fmt"
var g = "global"
func printLocal() {
l := "local"
fmt.Println(l)
fmt.Println(g)
}
func main() {
printLocal()
fmt.Println(g)
}
Outputlocal
global
global
Começamos declarando uma variável global g
, var g = "global"
. Na função main
, chamamos a função printLocal
, que declara uma variável local l
e a imprime, fmt.Println(l)
. Na sequência, o printLocal
imprime a variável global g
, fmt.Println(g)
. Embora g
não tenha sido definida dentro do printLocal
, ainda assim ela ficaria acessível, pois ela já havia sido declarada em um escopo global. Por fim, a função main
também imprime a variável g
.
Agora, vamos tentar chamar a variável local fora da função:
package main
import "fmt"
var g = "global"
func printLocal() {
l := "local"
fmt.Println(l)
}
func main() {
fmt.Println(l)
}
Outputundefined: l
Não podemos usar uma variável local fora da função para a qual ela foi atribuída. Se tentar fazer isso, receberá um erro undefined
(indefinido) ao compilar.
Vejamos outro exemplo em que usamos o mesmo nome de variável para uma variável global e uma variável local:
package main
import "fmt"
var num1 = 5
func printNumbers() {
num1 := 10
num2 := 7
fmt.Println(num1)
fmt.Println(num2)
}
func main() {
printNumbers()
fmt.Println(num1)
}
Output10
7
5
Neste programa, declaramos a variável num1
duas vezes. Primeiro, declaramos num1
no escopo global, var num1 = 5
e, novamente, dentro do escopo local da função printNumbers
, num1 := 10
. Ao imprimir num1
do programa main
, vemos o valor de 5
impresso. Isso se dá devido ao fato de que o main
enxerga somente a declaração da variável global. No entanto, quando imprimimos num1
a partir da função printNumbers
, ela verá a declaração local e irá imprimir o valor de 10
. Mesmo que o printNumbers
crie uma nova variável chamada num1
e lhe atribua o valor de 10
, ela não afeta a instância global do num1
com o valor de 5
.
Ao trabalhar com variáveis, você também precisa considerar quais partes do seu programa precisam de acesso a cada uma das variáveis e, desse modo, adotar variáveis globais ou locais,conforme o caso. Nos programas em Go, você descobrirá que as variáveis locais são normalmente mais comuns.
Constantes são como variáveis, exceto pelo fato de não poderem ser modificadas, uma vez que tenham sido declaradas. Constantes são úteis para definir um valor que será usado mais de uma vez no seu programa, mas não devem ser passíveis de alteração.
Por exemplo, se quiséssemos declarar a taxa de imposto de um sistema de carrinho de compra, poderíamos usar uma constante e então calcular o imposto em diferentes áreas do nosso programa. Dessa maneira, caso a taxa do imposto venha a ser alterada no futuro, somente teremos que alterar aquele valor em um ponto único de nosso programa. Se usássemos uma variável, correríamos o risco de alterar o valor por engano em algum lugar no nosso programa, o que, por sua vez, resultaria em um cálculo incorreto.
Para declarar uma constante, podemos usar a seguinte sintaxe:
const shark = "Sammy"
fmt.Println(shark)
OutputSammy
Se tentarmos modificar uma constante depois de ela ter sido declarada, vamos obter um erro de tempo de compilação:
Outputcannot assign to shark
As constantes podem ser untyped
[sem tipo]. Essa característica pode ser útil no trabalho com números, como dados do tipo números inteiros. Se a constante é untyped
, ela é convertida de maneira clara, ao passo que as constantes typed
não. Vamos ver como usar constantes:
package main
import "fmt"
const (
year = 365
leapYear = int32(366)
)
func main() {
hours := 24
minutes := int32(60)
fmt.Println(hours * year)
fmt.Println(minutes * year)
fmt.Println(minutes * leapYear)
}
Output8760
21900
21960
Se declarar uma constante com um tipo, ela será daquele tipo exato. Aqui, quando declaramos a constante leapYear
, nós a definimos como sendo do tipo de dados int32
. Portanto, trata-se de uma constante typed
, o que significa que ela só opera com tipos de dados int32
. A constante year
foi declarada sem tipo, assim, ela é considerada untyped
. Por causa disso, é possível usá-la com qualquer tipo de dado de número inteiro.
Quando a constante hours
tiver sido definida, o programa vai* inferir* que se trata de uma constante do tipo int
, pois não demos a ela - de maneira clara - um tipo, hours := 24
. Por outro lado, ao declararmos minutes
, nós a estaremos declarando explicitamente como sendo do tipo int32
, minutes := int32(60)
.
Agora, vejamos cada cálculo e o motivo pelo qual ele funciona:
hours * year
Nesse caso, hours
é um int
e years
é untyped. Quando o programa compila, ele converte explicitamente years
para um tipo int
, o que permite que a operação de multiplicação seja bem-sucedida.
minutes * year
Nesse caso, minutes
é um int32
e year
é untyped. Quando o programa compila, ele converte explicitamente years
para um int32
, o que permite que a operação de multiplicação seja bem-sucedida.
minutes * leapYear
Nesse caso, minutes
é um int32
e leapYear
é uma constante typed de int32
. Não há nada a ser feito pelo compilador desta vez, já que ambas as variáveis já são do mesmo tipo.
Se tentarmos multiplicar dois tipos que sejam typed
e não compatíveis, o programa não irá compilar:
fmt.Println(hours * leapYear)
Outputinvalid operation: hours * leapYear (mismatched types int and int32)
Neste caso, hours
foi inferida como sendo do tipo int
e leapYear
foi explicitamente declarada como sendo do tipo int32
. Como Go é uma linguagem de tipos, um int
e um int32
não são compatíveis em operações matemáticas. Para multiplicá-los, seria necessário converter um deles para int32
ou int
.
Neste tutorial, analisamos alguns dos casos de uso comuns de variáveis dentro da linguagem Go. As variáveis consistem em um importante bloco de construção de programação, servindo como símbolos que representam o valor de um tipo de dado que usamos em um programa.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Show de bola…