Pular para o conteúdo principal

Operadores

Operadores são símbolos que realizam operações em valores. Aqui está como diferentes linguagens lidam com operadores aritméticos, de comparação, lógicos e bit a bit.

Operadores Aritméticos e de Atribuição​

// Arithmetic
5 + 3; // 8 (addition)
5 - 3; // 2 (subtraction)
5 * 3; // 15 (multiplication)
5 / 3; // 1.6667 (division)
5 % 3; // 2 (modulo)
5 ** 3; // 125 (exponentiation)

// Increment / Decrement
let x = 5;
x++; // 6 (post-increment)
++x; // 7 (pre-increment)
x--; // 6 (post-decrement)

// Assignment
x += 3; // x = x + 3
x -= 2; // x = x - 2
x *= 4; // x = x * 4
x /= 2; // x = x / 2
x %= 3; // x = x % 3
x **= 2; // x = x ** 2

Operadores de Comparação e Lógicos​

// Comparison
5 == "5"; // true (loose equality)
5 === "5"; // false (strict equality)
5 != "5"; // false (loose inequality)
5 !== "5"; // true (strict inequality)
5 > 3; // true
5 >= 5; // true
5 < 10; // true
5 <= 5; // true

// Logical
true && false; // false (AND)
true || false; // true (OR)
!true; // false (NOT)

// Nullish coalescing
null ?? "default"; // "default"
undefined ?? "default"; // "default"
0 ?? "default"; // 0

// Optional chaining
user?.address?.city;
arr?.[0];
func?.();

Principais Conclusões​

  • Sobrecarga de operadores depende da linguagem -- C++ e Swift permitem operadores personalizados para tipos definidos pelo usuário; Rust usa traits como Add e Sub para sobrecarga. Python permite __add__, __sub__ e métodos similares para definir o comportamento de operadores. Go e Java proíbem sobrecarga de operadores para tipos do usuário, então você usa métodos (ex.: a.Add(b) em Go). Se você precisa de operadores expressivos para domínios numéricos ou específicos (ex.: matemática vetorial), prefira C++, Rust, Swift ou Python; se quer semântica mais simples e previsível, Go ou Java podem ser melhores.

  • Null coalescing (??) e optional chaining (?.) -- JavaScript, C#, Swift, PHP 8+ e Ruby suportam ?? para valores padrão quando um valor é null/undefined e ?. para acesso seguro a propriedades. Por exemplo, user?.address?.city ?? "unknown" evita erros de ponteiro nulo. Go e Rust não têm null; Go usa verificações explícitas de nil; Rust usa Option com unwrap_or(0) ou orelse 0 em Zig. C e Java não possuem equivalentes nativos e dependem de verificações manuais ou bibliotecas. Ao trabalhar com dados anuláveis, prefira linguagens com tratamento de null de primeira classe para reduzir boilerplate e bugs.

  • Comportamento de overflow difere -- Zig causa panic em overflow em builds de debug e faz wrapping em release; Rust oferece checked_add, wrapping_add e saturating_add para que você escolha o comportamento. C e C++ têm comportamento indefinido em overflow de inteiros, o que pode levar a problemas de segurança. JavaScript e Python usam inteiros de precisão arbitrária, então overflow é efetivamente inexistente. Para código numérico seguro, use as APIs checked do Rust ou os operadores explícitos do Zig; evite depender da semântica de overflow do C/C++.

  • Semântica de divisão inteira -- O / do Python 3 sempre retorna um float (5 / 3 é 1.666...); // é divisão inteira. C, Go, Rust e Java usam divisão truncada para inteiros (5 / 3 é 1). Isso afeta a portabilidade ao mover código numérico entre linguagens. Para consistência, use divisão inteira explícita (// em Python, @divTrunc em Zig) ou converta para float quando precisar de resultados fracionários. Ao portar algoritmos, verifique a semântica de divisão para evitar erros de arredondamento.

  • Operadores de incremento/decremento estão ausentes em algumas linguagens -- Rust, Python, Swift e Zig omitem ++ e --; Go os tem, mas apenas como instruções (ex.: x++), não expressões. Essas linguagens preferem x += 1 explícito para clareza e para evitar confusão entre pré/pós-incremento (ex.: i++ vs ++i). C, C++, C#, Java, JavaScript e PHP mantêm ++/--. Se você alterna entre linguagens, use x += 1 como padrão onde disponível para evitar problemas de portabilidade e bugs sutis.