Operadores em Go
Olá leitor, tudo bem? Espero que sim 🙃
Seja muito bem vindo a mais uma lição da Jornada GoLang do Portal da Micilini.
Hoje, você irá aprender sobre diversos tipos de operadores que nós podemos utilizar na linguagem, começando pelos:
- Operadores Aritméticos,
- Operadores de Atribuição,
- Operadores Lógicos,
- Operadores Unários,
- E... existe o operador Ternário em Go?
Além disso, veremos o funcionamento dos operadores bitwise, e o uso da biblioteca math
pare realizar operações matemáticas complexas.
Preparado? 😉
Criando seu projeto de testes
Dentro da pasta JornadaGoLang, nós iremos criar uma nova pasta chamada de 7-operadores-em-go
, onde dentro dela, vamos criar o nosso arquivo main.go
:
package main
func main(){
}
Feito isso, vamos começar aprendendo sobre os operadores aritméticos.
Usando operadores aritméticos em GoLang
Assim como em toda linguagem de programação, existem os operadores aritméticos, que são utilizados para realizar operações matemáticas básicas, como adição, subtração, multiplicação, divisão e o cálculo do resto de uma divisão.
Operadores como esses, são essenciais para que você possa manipular valores e números dentro do seu software.
Os principais operadores dessa categoria são:
- Adição, representado pelo sinal de
+
- Subtração, representado pelo sinal de
-
- Multiplicação, representado pelo sinal de
*
- Divisão, representado pelo sinal de
%
Vejamos agora, alguns exemplos de seu uso:
package main
import "fmt"
func main() {
a := 10
b := 3
fmt.Println("Adição:", a + b) // 13
fmt.Println("Subtração:", a - b) // 7
fmt.Println("Multiplicação:", a * b) // 30
fmt.Println("Divisão:", a / b) // 3 (inteiro)
fmt.Println("Módulo:", a % b) // 1
}
Simples não acha? Tudo o que fizemos, foi realizar uma operação matemática de forma tão crua quanto nós representamos isso numa folha de papel 😊
Além disso, também é possível armazenar dentro de uma variável o resultado de uma operação, vejamos:
c := 5 + 3
fmt.Println("Resultado:", c); // Resultado 8
É importante ressaltar que no GoLang, a divisão entre dois números inteiros retorna um resultado inteiro (truncando a parte decimal).
Sendo assim, se você deseja obter um valor decimal, você precisa converter os números para float64
da seguinte forma:
fmt.Println("Divisão com float:", float64(a) / float64(b)) // 3.3333
Operadores Bitwise em GoLang
Os operadores bitwise (ou operadores de manipulação de bits) trabalham diretamente nos bits que compõem os valores numéricos.
Eles são úteis para manipular dados em nível binário, o que pode ser mais eficiente em operações de baixo nível, como criptografia, compressão de dados e controle de hardware.
Vejamos abaixo, a lista completa dos operadores bitwise que podemos usar na linguagem:
AND (&): Retorna 1 apenas se ambos os bits forem 1.
OR (|): Retorna 1 se qualquer um dos bits for 1.
XOR (^): Retorna 1 se os bits forem diferentes.
AND NOT (&^): Zera os bits que são 1 no segundo operando.
Shift Left (<<): Desloca os bits para a esquerda (multiplica por potências de 2).
Shift Right (>>): Desloca os bits para a direita (divide por potências de 2).
Vejamos alguns exemplos na prática:
package main
import "fmt"
func main() {
a := 5 // 101 em binário
b := 3 // 011 em binário
fmt.Println("a AND b:", a & b) // 1 (0001)
fmt.Println("a OR b:", a | b) // 7 (0111)
fmt.Println("a XOR b:", a ^ b) // 6 (0110)
fmt.Println("a AND NOT b:", a &^ b) // 4 (0100)
fmt.Println("a << 1 (Left Shift):", a << 1) // 10 (1010)
fmt.Println("a >> 1 (Right Shift):", a >> 1) // 2 (0010)
}
Incrível não acha? 😊
Realizando operações aritméticas usando a biblioteca math
Já que estamos falando sobre operações matemáticas com GoLang, nada melhor do que te introduzir a uma biblioteca especializada nisso!
Neste caso, estou me referindo a biblioteca math
, que fornece uma ampla variedade de funções para operações matemáticas avançadas, como cálculo de potências, raízes, trigonometria, arredondamento e muito mais.
Para utilizar o pacote dentro do seu projeto, basta importá-lo da seguinte forma:
import "math"
📌 Para realizar operações básicas nós temos as principais funções:
math.Abs(x)
: Retorna o valor absoluto de um número.
math.Max(x, y)
: Retorna o maior entre dois números.
math.Min(x, y)
: Retorna o menor entre dois números.
math.Mod(x, y)
: Retorna o resto da divisão (módulo).
📌 Para realizar operações que envolvem potências e raízes nós temos:
math.Pow(x, y)
: Retorna a potência: x elevado a y.
math.Sqrt(x)
: Retorna a raiz quadrada.
math.Cbrt(x)
: Retorna a raiz cúbica.
math.Exp(x)
: Retorna a exponencial (e^x
).
math.Exp2(x)
: Retorna a potência de 2 (2^x
).
📌 Para realizar operações trigonométricas use:
math.Sin(x)
: Seno.
math.Cos(x)
: Cosseno.
math.Tan(x)
: Tangente.
math.Asin(x)
: Arco-seno (inverso do seno).
math.Acos(x)
: Arco-cosseno.
math.Atan(x)
: Arco-tangente.
Observação: Essas funções usam radianos, não graus. Para converter use a seguinte estratégia abaixo:
- Graus → Radianos: radianos := graus * (
math.Pi / 180
) - Radianos → Graus: graus := radianos * (
180 / math.P
i)
📌 Para realizar arredondamentos:
math.Floor(x)
: Arredonda para baixo (inteiro).
math.Ceil(x)
: Arredonda para cima (inteiro).
math.Round(x)
: Arredonda para o mais próximo.
math.Trunc(x)
: Trunca (corta a parte decimal).
📌 Por fim, caso você queira trabalhar com logaritmos:
math.Log(x)
: Logaritmo natural (base e).
math.Log2(x)
: Logaritmo base 2.
math.Log10(x)
: Logaritmo base 10.
Vejamos abaixo um exemplo completo da utilização dessa biblioteca:
package main
import (
"fmt"
"math"
)
func main() {
// Operações básicas
fmt.Println("Abs(-7.5):", math.Abs(-7.5))
fmt.Println("Max(3, 7):", math.Max(3, 7))
fmt.Println("Min(3, 7):", math.Min(3, 7))
fmt.Println("Mod(10, 3):", math.Mod(10, 3))
// Potências e raízes
fmt.Println("Pow(2, 3):", math.Pow(2, 3))
fmt.Println("Sqrt(25):", math.Sqrt(25))
fmt.Println("Cbrt(27):", math.Cbrt(27))
// Funções trigonométricas
fmt.Println("Sin(Pi/2):", math.Sin(math.Pi/2))
fmt.Println("Cos(0):", math.Cos(0))
fmt.Println("Tan(Pi/4):", math.Tan(math.Pi/4))
// Arredondamento
fmt.Println("Floor(3.7):", math.Floor(3.7))
fmt.Println("Ceil(3.1):", math.Ceil(3.1))
fmt.Println("Round(3.5):", math.Round(3.5))
fmt.Println("Trunc(3.9):", math.Trunc(3.9))
// Logaritmos
fmt.Println("Log(10):", math.Log(10))
fmt.Println("Log2(8):", math.Log2(8))
fmt.Println("Log10(100):", math.Log10(100))
}
Observação: As funções do pacote math
geralmente aceitam e retornam o tipo float64
. Se precisar trabalhar com outros tipos (como int), você deve fazer a conversão da seguinte forma:
x := 10
resultado := math.Sqrt(float64(x))
fmt.Println(resultado) // 3.162
Além disso, o pacote math
oferece algumas constantes matemáticas de forma padrão, como:
math.Pi
→ π (3.141592653589793)math.E
→ Número de Euler (2.718281828459045)math.Phi
→ Razão áurea (1.618033988749895)
Para mais informações consulte a documentação oficial da biblioteca 🙂
Operadores de Atribuição
Um operador de atribuição, como o próprio nome já nos diz, nada mais é do que um sinal que usamos para atribuir um determinado valor.
Você já sabe qual é?
Exatamente, é o famoso sinal de igual (=
), que por ventura, já o utilizamos durante a lição que falamos sobre Variáveis em Go.
x := 10
Entretanto, não existe apenas este tipo de operador de atribuição, mas alguns outros, vejamos:
=
: Realiza uma atribuição simples.
+=
: Realiza uma adição e atribuição.
-=
: Realiza uma subtração e atribuição.
*=
: Realiza uma multiplicação e atribuição.
/=
: Realiza uma divisão e atribuição.
%=
: Realiza um módulo (resto da divisão) e atribuição.
&=
: AND bit a bit e atribuição.
`
: OR bit a bit e atribuição.
^=
: XOR bit a bit e atribuição.
<<=
: Realiza um deslocamento à esquerda e atribuição.
>>=
: Realiza uma deslocamento à direita e atribuição.
Vejamos um exemplo prático, de todos os operadores que vimos acima em pleno funcionamento:
package main
import "fmt"
func main() {
var x int = 10
// Atribuição simples
fmt.Println("Valor inicial de x:", x)
// Adição e atribuição
x += 5
fmt.Println("x += 5 →", x) // 15
// Subtração e atribuição
x -= 3
fmt.Println("x -= 3 →", x) // 12
// Multiplicação e atribuição
x *= 2
fmt.Println("x *= 2 →", x) // 24
// Divisão e atribuição
x /= 4
fmt.Println("x /= 4 →", x) // 6
// Módulo e atribuição
x %= 5
fmt.Println("x %= 5 →", x) // 1
// Operações bit a bit
x = 10
x &= 6
fmt.Println("x &= 6 →", x) // 2
x |= 3
fmt.Println("x |= 3 →", x) // 3
x ^= 1
fmt.Println("x ^= 1 →", x) // 2
// Deslocamento de bits
x <<= 2
fmt.Println("x <<= 2 →", x) // 8
x >>= 1
fmt.Println("x >>= 1 →", x) // 4
}
Operadores Relacionais
Já os operadores relacionais, eles tem por objetivo comparar valores e retornar um valor booleano (true
ou false
).
Observação: operadores como esses são bastante utilizados em conjunto com estruturas de controle.
Os principais operadores relacionais que temos em GoLang, são:
==
: Igual a.
!=
: Diferente de.
<
: Menor que.
<=
: Menor ou igual a.
>
: Maior que.
>=
: Maior ou igual a.
Vejamos agora alguns exemplos do seu funcionamento:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // false (10 não é igual a 20)
fmt.Println("a != b:", a != b) // true (10 é diferente de 20)
fmt.Println("a < b:", a < b) // true (10 é menor que 20)
fmt.Println("a <= b:", a <= b) // true (10 é menor ou igual a 20)
fmt.Println("a > b:", a > b) // false (10 não é maior que 20)
fmt.Println("a >= b:", a >= b) // false (10 não é maior ou igual a 20)
// Comparando strings
nome1 := "Go"
nome2 := "Golang"
fmt.Println("nome1 == nome2:", nome1 == nome2) // false
fmt.Println("nome1 != nome2:", nome1 != nome2) // true
}
Interessante, não é mesmo? 😉
Operadores Lógicos
E é claro, não poderíamos nos esquecer dos operadores lógicos, que são usados para combinar ou inverter expressões booleanas (true
ou false
).
Sendo fundamentais em estruturas condicionais e outras lógicas de controle que ainda veremos em lições futuras.
Os principais operadores lógicos, são esses:
&&
: AND lógico (E).
||: OR lógico (OU).
!
: NOT lógico (NÃO).
Vejamos um exemplo de seu funcionamento:
package main
import "fmt"
func main() {
a := true
b := false
// Operador AND (&&) - Ambas as condições devem ser verdadeiras
fmt.Println("a && b:", a && b) // false (true E false → false)
fmt.Println("true && true:", true && true) // true
// Operador OR (||) - Pelo menos uma condição deve ser verdadeira
fmt.Println("a || b:", a || b) // true (true OU false → true)
fmt.Println("false || false:", false || false) // false
// Operador NOT (!) - Inverte o valor booleano
fmt.Println("!a:", !a) // false (inverte true → false)
fmt.Println("!b:", !b) // true (inverte false → true)
}
Observação: os exemplos abaixo usam estruturas de controle que você aprenderá em lições futuras, portanto, fique tranquilo caso você estiver se sentindo um pouco perdido 😉
Começando pelo &&
, ele só retorna true
se ambas as condições forem verdadeiras, exemplo:
idade := 25
habilitado := true
if idade >= 18 && habilitado {
fmt.Println("Pode dirigir.")
}
No caso do ||
, ele retorna true
se pelo menos uma das condições forem verdadeiras:
temperatura := 35
if temperatura < 0 || temperatura > 30 {
fmt.Println("Clima extremo.")
}
Por fim, nós temos o !
, que inverte o valor booleano, nesse caso, true
se torna false
, e false
se torna true
:
ativo := true
if !ativo {
fmt.Println("Usuário inativo.")
} else {
fmt.Println("Usuário ativo.")
}
Agora falando um pouco sobre algumas curiosidades do GoLang, você sabia que se a primeira condição em &&
for false
, a segunda não é avaliada?
Sim, isso é totalmente verdade, e o GoLang opera dessa forma, portanto, muito cuidado ao utilizar o &&
.
Além disso, no caso do ||
, se a primeira condição for verdadeira, a segunda é totalmente ignorada, sabia disso?
Vejamos alguns exemplos:
x := 10
if x > 5 || x/0 == 1 { // x/0 nunca será avaliado (evita erro de divisão por zero)
fmt.Println("Executa sem erro.")
}
Operadores Unários
Quando falamos de operadores unários, estamos nos referindo a comandos que agem sobre apenas um único operando (valor ou variável).
Mas como assim, um operando?
Um operando é o valor ou a variável sobre o qual um operador realiza uma operação.
Em outras palavras, é o "alvo" que o operador irá modificar ou avaliar. No caso dos operadores unários, eles só precisam de um único valor para funcionar, diferentemente dos operadores binários, que exigem dois operandos.
Por exemplo, vamos analisar a seguinte expressão abaixo:
x := -10
No código acima, nós temos:
- Operador:
-
(inversão de sinal) - Operando:
10
Sendo assim, podemos dizer que a variável x
, armazena o valor -10
.
Note que o operador unário -
age sobre o valor 10
, tornando-o negativo. Fazendo com que apenas um valor seja o suficiente para que a operação seja realizada.
Em Go, os operadores unários são usados para realizar tarefas específicas, como inverter valores, trabalhar com ponteiros, ou manipular bits de forma direta. Eles são simples, mas extremamente úteis para operações rápidas e eficientes.
Vejamos os principais operadores unários que temos disponíveis em Go:
+
: Transforma em um valor positivo.
-
: Transforma em um valor negativo (inverte o sinal).
++
: Incrementa um valor (❌ não é permitido em Go)
--
: Decrementa um valor (❌ não é permitido em Go)
!
: Negação lógica (inverte booleano).
^
: Complemento bit a bit (NOT).
&
: Endereço de memória (referência).
*
: Desreferência (valor do ponteiro).
package main
import "fmt"
func main() {
// 1. Operador de Sinal (+ e -)
a := 10
b := -a
fmt.Println("+a:", +a) // Saída: 10
fmt.Println("-a:", b) // Saída: -10
// 2. Operador de Negação Lógica (!)
ativo := true
fmt.Println("!ativo:", !ativo) // Saída: false
// 3. Operador de Endereço (&) e Desreferência (*)
x := 42
ptr := &x // & obtém o endereço de memória de x
fmt.Println("Endereço de x:", ptr)
fmt.Println("Valor apontado por ptr:", *ptr) // * acessa o valor no endereço
// 4. Operador de Complemento Bit a Bit (^)
num := 5 // Em binário: 101
fmt.Println("^num:", ^num) // Inverte os bits: -6 (em complemento de dois)
}
Existe o Operador Ternário em Go?
Diferente de outras linguagens de programação, onde você consegue realizar uma estrutura de controle de forma resumida, como é o caso do Javascript:
let resultado = (idade >= 18) ? "Maior de idade" : "Menor de idade";
console.log(resultado);
No caso do GoLang, ele não possui suporte ao operador ternário de forma nativa, o que nos obriga a utilizar estruturas if
e else
inteiras:
package main
import "fmt"
func main() {
idade := 20
var resultado string
if idade >= 18 {
resultado = "Maior de idade"
} else {
resultado = "Menor de idade"
}
fmt.Println(resultado)
}
No caso do GoLang, ele prioriza a clareza e simplicidade do código, e a ausência do operador ternário evita abreviações confusas, tornando a lógica mais legível usando if/else
.
Repositório da lição
Todos os arquivos relacionados com esta lição, podem ser encontrados nos seguintes repositórios abaixo:
Conclusão
Nesta lição, você aprendeu a utilizar diversos tipos de operadores, como os aritméticos, relacionais, de atribuição e unários.
Na próxima lição, vamos entrar nas principais estruturas de controle suportados pelo GoLang, como If/Else
, For
e Switch
.
Até a próxima 🙂