DEV Community

Linive
Linive

Posted on

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 

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*/

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) 

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) 

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

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

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

Top comments (3)

Collapse
 
guilesuica profile image
Guilherme Lira

Parabéns pelo conteúdo Linive
Brabo demais!!!

Collapse
 
cehasli profile image
Cehasli de Castro

Excelente explicação.

Collapse
 
whoisterry profile image
Terry Richards

Thank you! I used Chrome translate to follow.