Uint vs Int. Qual a diferença em Go?

linivecristine

Linive

Posted on May 20, 2020

Uint vs Int. Qual a diferença em Go?

⚠️ Alerta: Antes de entrar nesse assunto, é necessário um conhecimento básico de tipos primitivos e medidas de armazenamento.

Já deu uma lida? Então vamos lá!

Alt Text

◾ Uint - unsigned int

Unsigned significa sem sinal, não assinalado. Então é exatamente isso que ele é, um int que desconsidera o sinal.

Moleza demais

Agora vamos para as suas variações:

  • uint8
  • uint16
  • uint32
  • uint64

Já mencionamos algumas delas em outros posts, mas hoje vamos entrar em detalhes.

  • Uint8

Sabemos que esse 8 faz referência a quantidade de bits, que é uma medida de armazenamento. Esses bits irão definir a capacidade desse tipo.

Mas como descobrimos a capacidade de armazenamento de um tipo, tendo apenas sua quantidade de bits? É fácil, tem uma fórmula para isso.

Alt Text
Esse n é a quantidade de bits.

No caso do uint8, a formula fica assim:
Alt Text

O Resultado dessa conta é 256. Então uma variável do tipo uint8 tem capacidade de armazenamento de 0 a 255. Nunca esqueçam do zero, ele também conta!.

Vocês devem esta se perguntando: "ok. Mas qual a importância disso?"

Problemas podem ocorrer se passarmos dessa capacidade máxima, esse problema se chama overflow e a NASA o conhece muito bem...

Alt Text
370 milhões de dólares por um erro de integer overflow. Se quiser conhecer mais a história: aqui

Como ocorre um overflow?

1°: Podemos tentar atribuir um valor maior que a capacidade



var x uint8 = 1000

fmt.Println(x) 
//Um erro será apresentado: 1000 overflows uint8
//Esse código não será executado 


Enter fullscreen mode Exit fullscreen mode

Esse aqui é o melhor caso, ou menos pior, pois o erro será apresentado e o código não será executado. A mensagem indicará qual é o erro e assim podemos corrigi-lo.

2°: Vamos causar o ovewflow durante o código



var x uint8 = 255

fmt.Println(x) 
/*Esse código irá executar sem nenhum erro, pois não ultrapassamos 
o limite de armazenamento da variável*/


Enter fullscreen mode Exit fullscreen mode

Nenhum erro aconteceu, mas sabemos que o número atribuído a variável está no limite de sua capacidade. Isso é bem perigoso, pois no meio do código pode ocorrer um incremento e o overflow irá acontecer.



var x uint8 = 255

x++ //Um incremento. O overflow aconteceu, x agora vale 256

fmt.Println(x) 


Enter fullscreen mode Exit fullscreen mode

O que vocês acham que vai acontecer? O código não irá executar ou irá apresentar um erro?

Nenhum das opções. O código continuará funcionando normalmente. Ai que está o perigo, nenhuma mensagem irá aparecer.

Sabe o que irá acontecer com a variável? Ela volta a ser zero. x = 0 .

Agora imagine isso em um código gigante e com inúmeras variáveis. Imagine o trabalho para achar qual delas sofreu overflow, e a pior parte vai ser deduzir que o problema é de overflow, já que nenhum erro é apresentado.

Falta só um detalhe para finalizar o int8.

Vocês lembram quem um byte é igual a 8 bits? Sabe quem tem 8 bits? Exatamente, o uint8. Um byte é igual a uint8 e podemos declarar uma variável como byte, o resultado será o mesmo.



var x byte = 255 // byte = uint8

fmt.Println(x) 


Enter fullscreen mode Exit fullscreen mode

Essa lógica do uint8 se aplica a todas suas variações.

  • uint16
  • uint32
  • uint64

O que irá mudar é a capacidade de armazenamento, já que os bits são diferentes.

◾ Int - signed int

Signed significa assinalado, com sinal. Então o int irá considerar o sinal dos números.

Essas são suas variações:

  • int8
  • int16
  • int32
  • int64

As variações são as mesmas, a única diferença é a questão do sinal. O que isso irá mudar na prática?

Bem, o armazenamento do uint começava do zero, pois ele não considera os números negativos. Então se sua capacidade é de 256, vai de 0 a 255.

Alt Text

Os ints consideram o sinal, então eles utilizam tanto o lado positivo quanto o negativo.

Alt Text

Então se teoricamente a capacidade de armazenamento for de 256, ele deve ir de 0 a 255, mas também deve ir para o lado negativo, de -1 a -256.

Espero que tenham entendido, mas se não ficou claro, vocês vão entender mais para frente.

  • Int8

Se vocês estão achando que o int8 irá armazenar 256 assim como o uint8, vocês estão... errados.

Alt Text

Eles não serão iguais porque um dos bits do int8 será destinado ao sinal, então apenas 7 entrarão no cálculo.

Alt Text

O resultado será 128. Então vai de 0 a 127 e de -1 a -128.

Overflow funciona exatamente da mesma forma, mas levando em consideração os números negativos.



var x int8 = 128 // Overflow, pois vai até 127
var y int8 = -129// Overflow, pois vai até -128


Enter fullscreen mode Exit fullscreen mode

Essa mesma lógica se aplica as outras variações.

  • int16
  • int32
  • int64

Uma informação importante. Vocês lembras das runes? rune é um caractere de string. Uma rune é igual a um int32, e assim como no caso byte/uint8, podemos declarar uma variável com rune.



var x rune = 127 //rune = int32


Enter fullscreen mode Exit fullscreen mode

Outro ponto que não devemos esquecer é que nenhum tipo é igual a outro. Um int não é igual a um int8, uint32 não é igual a int32 e assim por diante. As únicas coisas que são iguais são: rune = int32 e byte = uint8, pense neles como apelidos.

Essas são as diferenças entre uint e int, espero que tenham entendido.

Este é o curso que estou seguindo, recomendo!

Já falamos muito por hoje, vejo vocês amanhã!

Alt Text

💖 💪 🙅 🚩
linivecristine
Linive

Posted on May 20, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related