One place for hosting & domains

      variáveis

      Como ler e definir variáveis de ambiente e de shell no Linux


      Introdução

      Ao interagir com seu servidor através de uma sessão do shell, há muitas informações compiladas pelo seu shell para determinar o seu comportamento e acesso a recursos. Algumas dessas configurações estão contidas nas definições de configuração enquanto outras são determinadas pela entrada do usuário.

      Uma das maneiras pela qual o shell mantém o controle de todas essas configurações e detalhes é através de uma área mantida por ele chamada ambiente. O ambiente é uma área que o shell compila toda vez que inicia uma sessão que contém variáveis que definem propriedades do sistema.

      Neste guia, vamos discutir como interagir com o ambiente e ler ou definir variáveis de ambiente e de shell interativamente e por arquivos de configuração.

      Como o ambiente e variáveis de ambiente funcionam

      Sempre que uma sessão do shell é gerada, um processo ocorre para coletar e compilar informações que devem estar disponíveis ao processo shell e seus processos filhos. Ele obtém os dados para essas configurações de uma variedade de arquivos e configurações distintas no sistema.

      O ambiente fornece um meio pelo qual o processo shell pode obter ou definir configurações e, por sua vez, passá-las aos seus processos filhos.

      O ambiente é implementado como strings que representam pares de chave-valor. Se múltiplos valores forem passados, eles são normalmente separados por caracteres dois-pontos (:). Cada par será geralmente parecido com isto:

      KEY=value1:value2:...
      

      Se o valor contiver um espaço em branco significativo, as aspas são usadas:

      KEY="value with spaces"
      

      As chaves nesses cenários são variáveis. Elas podem ser de dois tipos, variáveis de ambiente ou variáveis de shell.

      As variáveis de ambiente são variáveis definidas para a sessão atual do shell e são herdades por qualquer shell ou processo filho. As variáveis de ambiente são usadas para passar informações para processos gerados a partir do shell.

      As variáveis de shell são variáveis contidas exclusivamente no shell no qual foram configuradas ou definidas. Geralmente, elas são usadas para manter o controle de dados efêmeros, como o diretório de trabalho atual.

      Por convenção, esses tipos de variáveis são geralmente definidos usando somente letras maiúsculas. Isso ajuda os usuários a distinguir as variáveis de ambiente em outros contextos.

      Imprimindo variáveis de ambiente e de shell

      Cada sessão do shell mantém o controle de suas variáveis de ambiente e de shell. Podemos acessá-las de algumas maneiras diferentes.

      É possível ver uma lista de todas as nossas variáveis de ambiente usando os comandos env ou printenv. Em seu estado padrão, elas devem funcionar exatamente da mesma maneira:

      Output

      SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv

      Isso é algo bastante típico para o resultado tanto de printenv quanto env. A diferença entre os dois comandos só é aparente em suas funcionalidades mais específicas. Por exemplo, com printenv, é possível solicitar os valores de variáveis individuais:

      Output

      /bin/bash

      Por outro lado, o env lhe permite modificar o ambiente no qual os programas são executados passando um conjunto de definições de variável em um comando, como este:

      • env VAR1="value" command_to_run command_options

      Considerando que, assim como aprendemos acima, os processos filhos normalmente herdam as variáveis de ambiente do processo pai, isso lhe dá a oportunidade de substituir valores ou adicionar variáveis adicionais ao filho.

      Como você pode ver no resultado do nosso comando printenv, há uma quantidade razoável de variáveis de ambiente configuradas em nossos arquivos e processos de sistema sem a nossa intervenção.

      Esses comandos mostram as variáveis de ambiente, mas como vemos as variáveis de shell?

      O comando set pode ser usado para isso. Se digitarmos set sem nenhum parâmetro adicional, iremos receber uma lista de todas as variáveis de shell, variáveis de ambiente, variáveis locais e funções shell:

      Output

      BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .

      Normalmente, essa é uma lista enorme. Provavelmente, é desejável canalizá-la em um programa pager para manusear mais facilmente todo o resultado:

      A quantidade de informações adicionais recebidas de volta pode parecer muito grande. Provavelmente, não é necessário conhecer todas as funções bash que estão definidas, por exemplo.

      Podemos limpar o resultado especificando que set deve operar no modo POSIX, que não irá imprimir as funções shell. Podemos executá-lo em um subshell para que ele não altere nosso ambiente atual:

      Isso irá listar todas as variáveis de ambiente e de shell que estão definidas.

      Podemos tentar comparar esse resultado com o resultado dos comandos env ou printenv para tentar obter uma lista com apenas as variáveis de shell, mas isso não será perfeito, devido às diferentes maneiras pelas quais esses comandos geram os resultados:

      • comm -23 <(set -o posix; set | sort) <(env | sort)

      Isso provavelmente ainda irá incluir algumas variáveis de ambiente, pois o comando set exibe valores entre aspas, enquanto o printenv e env não colocam os valores de strings entre aspas.

      Isso deve lhe dar uma boa noção das variáveis de ambiente e de shell que estão definidas em sua sessão.

      Essas variáveis são usadas para todo tipo de coisa. Elas oferecem uma forma alternativa de definir valores persistentes para a sessão entre processos, sem gravar alterações em um arquivo.

      Variáveis de ambiente e de shell comuns

      Algumas variáveis de ambiente e de shell são muito úteis e são referenciadas com bastante frequência. Aqui estão algumas variáveis de ambiente comuns que você deve encontrar:

      • SHELL: descreve o shell que irá interpretar todos os comandos que você digitar. Geralmente, isso será bash por padrão, mas outros valores podem ser definidos caso prefira outras opções.
      • TERM: especifica o tipo de terminal a ser emulado ao executar o shell. Diferentes terminais de hardware podem ser emulados para diferentes requisitos de operação. Normalmente, não será necessário se preocupar com isso.
      • USER: o usuário que está atualmente conectado.
      • PWD: o diretório de trabalho atual.
      • OLDPWD: o diretório de trabalho anterior. Isso é mantido pelo shell para retornar ao seu diretório anterior executando cd -.
      • LS_COLORS: define códigos de cor que são usados para adicionar um resultado de cor opcional ao comando ls. Isso é usado para distinguir diferentes tipos de arquivos e fornecer mais informações ao usuário em um olhar rápido.
      • MAIL: o caminho para a caixa de correio do usuário atual.
      • PATH: uma lista de diretórios que o sistema irá verificar ao procurar por comandos. Quando um usuário digita um comando, o sistema irá verificar diretórios neste pedido para o executável.
      • LANG: a configuração atual de idioma e localização, incluindo a codificação de caracteres.
      • HOME: o diretório base do usuário atual.
      • _: o comando executado anteriormente mais recente.

      Além dessas variáveis de ambiente, algumas variáveis de shell que você verá com frequência são:

      • BASHOPTS: a lista de opções que foram usadas quando o bash foi executado. Isso pode ser útil para descobrir se o ambiente do shell irá operar da maneira que você deseja.
      • BASH_VERSION: a versão do bash sendo executada, de forma legível por humanos.
      • BASH_VERSINFO: a versão do bash, em saída legível por máquina.
      • COLUMNS: o número de colunas de largura que estão sendo usadas para exibir um resultado na tela.
      • DIRSTACK: a pilha de diretórios que estão disponíveis com os comandos pushd e popd.
      • HISTFILESIZE: número de linhas de histórico de comando armazenadas em um arquivo.
      • HISTSIZE: número de linhas de histórico de comando permitidas na memória.
      • HOSTNAME: o nome de host do computador neste momento.
      • IFS: o separador de campo interno para separar entradas na linha de comando. Por padrão, é um espaço.
      • PS1: a de definição de prompt de comando primário. Isso é usado para definir a aparência do seu prompt quando inicia a sessão do shell. O PS2 é usado para declarar prompts secundários para quando um comando ocupa várias linhas.
      • SHELLOPTS: opções de shell que podem ser definidas com a opção set.
      • UID: o UID do usuário atual.

      Definindo variáveis de ambiente e de shell

      Para entender melhor a diferença entre as variáveis de ambiente e de shell, e para apresentar a sintaxe para definir essas variáveis, faremos uma pequena demonstração.

      Criando variáveis de shell

      Vamos começar definindo uma variável de shell dentro de nossa sessão atual. Isso é de fácil execução. Precisamos especificar apenas um nome e um valor. Vamos aderir à convenção de manter todas as letras maiúsculas para o nome da variável e defini-las em uma string simples.

      Aqui, usamos aspas, pois o valor de nossa variável contém um espaço. Além disso, usamos aspas simples, pois o ponto de exclamação é um caractere especial no bash do shell que normalmente expande para o histórico do bash se não forem colocados caracteres de escape ou colocado entre aspas simples.

      Agora, temos uma variável de shell. Essa variável está disponível em nossa sessão atual, mas não será passada para processos filhos.

      Podemos ver isso usando o grep para nossa nova variável dentro do resultado de set:

      Output

      TEST_VAR='Hello World!'

      Podemos verificar se essa não é uma variável de ambiente testando a mesma coisa com o printenv:

      Nenhum resultado deve ser retornado.

      Vamos aproveitar isso como uma oportunidade para demonstrar uma maneira de acessar o valor de qualquer variável de ambiente ou de shell.

      Output

      Hello World!

      Como você pode ver, faça referência ao valor de uma variável executando-a com um sinal de $. O shell recebe isso e entende que deve substituir o valor da variável quando se depara com isso.

      Então, agora, temos uma variável de shell. Ela não deve ser passada para nenhum processo filho. Podemos gerar um novo shell do bash de dentro do atual para demonstrar isso:

      Se digitarmos bash para gerar um shell filho e então tentarmos acessar o conteúdo da variável, nada será retornado. Isso é exatamente o que esperávamos.

      Volte para o nosso shell original digitando exit:

      Criando variáveis de ambiente

      Agora, vamos transformar nossa variável de shell em uma variável de ambiente. Podemos fazer isso exportando a variável. O comando para isso é nomeado apropriadamente:

      Isso irá alterar nossa variável para uma variável de ambiente. Podemos verificar isso olhando nossa listagem de ambiente novamente:

      Output

      TEST_VAR=Hello World!

      Desta vez, nossa variável aparece. Vamos tentar nosso experimento com o nosso shell filho novamente:

      Output

      Hello World!

      Ótimo! Nosso shell filho recebeu a variável definida pelo seu pai. Antes de sairmos deste shell filho, vamos tentar exportar outra variável. Podemos definir variáveis de ambiente em um único passo, desta forma:

      • export NEW_VAR="Testing export"

      Teste se ele foi exportado como uma variável de ambiente:

      Output

      NEW_VAR=Testing export

      Agora, vamos voltar para o nosso shell original:

      Vamos ver se nossa nova variável está disponível:

      Nada é retornado.

      Isso ocorre porque variáveis de ambiente são passadas apenas para processos filhos. Não existe uma maneira integrada de definir variáveis de ambiente do shell pai. Isso é bom na maioria dos casos e impede que os programas afetem o ambiente operacional de onde foram chamados.

      A variável NEW_VAR foi definida como uma variável de ambiente em nosso shell filho. Essa variável estaria disponível para si mesma e qualquer um de seus shells e processos filhos. Quando saímos e voltamos para o nosso shell principal, aquele ambiente foi destruído.

      Rebaixando e removendo variáveis

      Ainda temos nossa variável TEST_VAR definida como uma variável de ambiente. Podemos revertê-la para uma variável de shell digitando:

      Ela não é mais uma variável de ambiente:

      No entanto, ela ainda é uma variável de shell:

      Output

      TEST_VAR='Hello World!'

      Se quisermos remover completamente uma variável, seja ela de ambiente ou de shell, podemos fazê-lo com o comando unset:

      Podemos verificar se ela não está mais definida:

      Nada é retornado porque a variável foi removida.

      Definindo variáveis de ambiente no login

      Já mencionamos que muitos programas usam variáveis de ambiente para decidir as especificações de como operar. Não é interessante precisar definir variáveis importantes toda vez que iniciarmos uma sessão do shell. Além disso, já vimos quantas já são definidas no login. Sendo assim, como criamos e definimos variáveis automaticamente?

      Esse é realmente um problema mais complexo do que parece, devido aos inúmeros arquivos de configuração que o shell do bash lê, dependendo de como é iniciado.

      A diferença entre as sessões do shell com login, sem login, interativa e não interativa

      O shell do bash lê arquivos de configuração diferentes dependendo da forma como a sessão é iniciada.

      Uma distinção entre sessões diferentes é se o shell está sendo gerado como uma sessão com login ou sem login.

      Um shell com login é uma sessão de shell que começa pela autenticação do usuário. Se você estiver entrando em uma sessão de terminal ou via protocolo SSH e autenticar-se, sua sessão de shell será definida como um shell com login.

      Se você iniciar uma nova sessão de shell dentro de sua sessão autenticada, como fizemos chamando o comando bash do terminal, uma sessão sem login de shell será iniciada. Seus detalhes de autenticação não foram solicitados quando você iniciou seu shell filho.

      Outra distinção que pode ser feita é se uma sessão de shell é ou não interativa.

      Uma sessão de shell interativa é uma sessão que está anexada a um terminal. Uma sessão de shell não interativa é uma que não está anexada a uma sessão de terminal.

      Dessa forma, cada sessão de shell é classificada como sendo com ou sem login e interativa ou não interativa.

      Uma sessão normal que começa com o SSH é geralmente uma sessão de shell interativa com login. Um script executado a partir da linha de comando é geralmente executado em um shell não interativo e sem login. Uma sessão de terminal pode ser qualquer combinação dessas duas propriedades.

      A classificação da sessão de shell como sendo com ou sem login tem implicações sobre quais arquivos são lidos para inicializar a sessão de shell.

      Uma sessão iniciada como sessão com login lerá detalhes de configuração do arquivo /etc/profile primeiro. Em seguida, ela irá procurar pelo primeiro arquivo de configuração de shell de login no diretório base do usuário para obter detalhes de configuração específicos do usuário.

      Ela lê o primeiro arquivo que achar entre ~/.bash_profile, ~/.bash_login e ~/.profile e não lê nenhum arquivo adicional.

      Em contraste, uma sessão definida como um shell sem login lerá /etc/bash.bashrc e então o arquivo ~/.bashrc específico do usuário para compilar seu ambiente.

      Os shells não interativos leem a variável de ambiente chamada BASH_ENV e o arquivo especificado para definir o novo ambiente.

      Implementando variáveis de ambiente

      Como você pode ver, há uma grande variedade de arquivos diferentes que normalmente precisaríamos observar para colocar nossas configurações.

      Isso oferece uma grande flexibilidade que pode ajudar em situações específicas em que queremos certas configurações em um shell com login e outras configurações em um shell sem login. No entanto, na maior parte do tempo, vamos querer as mesmas configurações em ambas as situações.

      Felizmente, a maioria das distribuições Linux configuram os arquivos de configuração de login para originar os arquivos de configuração sem login. Isso significa que é possível definir as variáveis de ambiente que desejar tanto em arquivos com login, quanto nos sem login. Eles serão então lidos em ambos os cenários.

      Normalmente, vamos definir variáveis de ambiente específicas para cada usuário, e geralmente vamos querer que nossas configurações estejam disponíveis tanto em shells com login quanto sem login. Isso significa que o lugar para definir essas variáveis é no arquivo ~/.bashrc.

      Abra esse arquivo agora:

      Provavelmente, ele já irá conter uma quantidade considerável de dados. A maioria das definições aqui presentes são para definir opções do bash, que não estão relacionadas às variáveis de ambiente. É possível definir variáveis de ambiente da mesma forma que você faria da linha de comando:

      Qualquer nova variável de ambiente pode ser adicionada em qualquer lugar no arquivo ~/.bashrc, desde que não seja colocada no meio de outro comando ou loop for. Em seguida, podemos salvar e fechar o arquivo. Da próxima vez que você iniciar uma sessão do shell, sua declaração de variável de ambiente será lida e transmitida para o ambiente do shell. É possível forçar sua sessão atual a ler o arquivo agora digitando:

      Se precisar definir variáveis em todo o sistema, pense em adicioná-las ao /etc/profile, /etc/bash.bashrc ou /etc/environment.

      Conclusão

      As variáveis de ambiente e de shell estão sempre presentes em suas sessões de shell e podem ser muito úteis. Elas são uma maneira interessante para um processo pai definir detalhes de configuração para seus filhos, além de representarem uma maneira de definir opções fora dos arquivos.

      Isso oferece muitas vantagens em situações específicas. Por exemplo, a implantação de alguns mecanismos dependem de variáveis de ambiente para configurar informações de autenticação. Isso é útil, pois não requer a manutenção desses arquivos que podem ser vistos por partes externas.

      Existem muitos outros cenários, mais mundanos e comuns em que você precisará ler ou alterar o ambiente do seu sistema. Essas ferramentas e técnicas devem lhe dar uma boa base para fazer essas alterações e usá-las corretamente.



      Source link

      Como usar variáveis e constantes em Go


      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.

      Entendendo as variáveis

      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.

      Sobre as variáveis na linguagem Go

      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.

      Exemplo de variável na linguagem Go

      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:

      • o nome da variável (i)
      • a atribuição de uma declaração curta da variável (:=)
      • o valor que está sendo associado ao nome da variável (1032049348)
      • o tipo de dados inferido pela Go (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)
      }
      

      Output

      1032049348

      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)
      

      Output

      1032048535

      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)
      }
      

      Output

      221

      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.

      Declarando as variáveis

      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.

      Valores zero

      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 = %+vn", a, a)
          fmt.Printf("var b %T = %qn", b, b)
          fmt.Printf("var c %T = %+vn", c, c)
          fmt.Printf("var d %T = %+vnn", d, d)
      }
      

      Output

      var 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.

      Nomeando variáveis: regras e estilo

      A nomeação de variáveis é bastante flexível, mas existem algumas regras a serem lembradas:

      • Os nomes das variáveis devem consistir em apenas uma palavra (ou seja, sem nenhum espaço).
      • Os nomes das variáveis devem ser constituídos apenas de letras, números e sublinhados (_).
      • Os nomes das variáveis não podem começar com um número.

      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 = %qn", 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.

      Reatribuindo variáveis

      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)
      }
      

      Output

      76 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:

      Output

      cannot 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
      

      Output

      s 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
      

      Output

      no 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.

      Atribuição múltipla

      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)
      

      Output

      shark 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.

      Variáveis globais e locais

      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)
      }
      

      Output

      local 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)
      }
      

      Output

      local 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)
      }
      
      

      Output

      undefined: 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)
      }
      

      Output

      10 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

      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)
      

      Output

      Sammy

      Se tentarmos modificar uma constante depois de ela ter sido declarada, vamos obter um erro de tempo de compilação:

      Output

      cannot 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)
      }
      

      Output

      8760 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)
      

      Output

      invalid 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.

      Conclusão

      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.



      Source link