Operadores de Zig
Los operadores y las expresiones son componentes básicos utilizados en los lenguajes de programación para realizar diversas operaciones.
En Zig, los operadores se pueden clasificar en varias categorías, incluyendo operadores aritméticos, operadores relacionales, operadores lógicos, operadores de bits, operadores de asignación y otros operadores.
A continuación se presentan las explicaciones detalladas y ejemplos de cada tipo de operador.
Operadores aritméticos
| Operador | Descripción |
|---|---|
| + | Adición (suma) |
| - | Sustracción (resta) |
| * | Multiplicación |
| / | División |
| % | Resto (operación módulo) |
Ejemplo
pub fn main() void {
const a: i32 = 5;
const b: i32 = 3;
const add: i32 = a + b;
const subtract: i32 = a - b;
const multiply: i32 = a * b;
const divide: i32 = a / b;
const remainder: i32 = a % b;
std.debug.print("a + b = {}\n", .{add});
std.debug.print("a - b = {}\n", .{subtract});
std.debug.print("a * b = {}\n", .{multiply});
std.debug.print("a / b = {}\n", .{divide});
std.debug.print("a % b = {}\n", .{remainder});
}
El resultado de la compilación es:
a + b = 8 a - b = 2 a * b = 15 a / b = 1 a % b = 2
Operadores relacionales
| Operador | Descripción |
|---|---|
| == | Igual a |
| != | No igual a (distinto de) |
| > | Mayor que |
| < | Menor que |
| >= | Mayor o igual que |
| <= | Menor o igual que |
Ejemplo
pub fn main() void {
const a: i32 = 5;
const b: i32 = 3;
const equal: bool = a == b;
const not_equal: bool = a != b;
const greater: bool = a > b;
const less: bool = a < b;
const greater_equal: bool = a >= b;
const less_equal: bool = a <= b;
std.debug.print("a == b: {}\n", .{equal});
std.debug.print("a != b: {}\n", .{not_equal});
std.debug.print("a > b: {}\n", .{greater});
std.debug.print("a < b: {}\n", .{less});
std.debug.print("a >= b: {}\n", .{greater_equal});
std.debug.print("a <= b: {}\n", .{less_equal});
}
El resultado de la compilación es:
a == b: false a != b: true a > b: true a < b: false a >= b: true a <= b: false
Operadores lógicos
| Operador | Descripción |
|---|---|
| and | Y lógico (AND) |
| or | O lógico (OR) |
| ! | Negación lógica (NOT) |
Ejemplo
pub fn main() void {
const a: bool = true;
const b: bool = false;
const and_result: bool = a and b;
const or_result: bool = a or b;
const not_result: bool = !a;
std.debug.print("a and b: {}\n", .{and_result}); // false
std.debug.print("a or b: {}\n", .{or_result}); // true
std.debug.print("!a: {}\n", .{not_result}); // false
}
El resultado de la compilación es:
a and b: false a or b: true !a: false
Operadores de bits
| Operador | Descripción |
|---|---|
| & | Y bit a bit (AND) |
| | | O bit a bit (OR) |
| ^ | XOR bit a bit |
| ~ | Complemento bit a bit (NOT) |
| << | Desplazamiento a la izquierda |
| >> | Desplazamiento a la derecha |
Ejemplo
pub fn main() void {
const a: i32 = 5; // 0101
const b: i32 = 3; // 0011
const bit_and: i32 = a & b; // 0001
const bit_or: i32 = a | b; // 0111
const bit_xor: i32 = a ^ b; // 0110
const bit_not: i32 = ~a; // 11111111111111111111111111111010
const left_shift: i32 = a << 1; // 1010
const right_shift: i32 = a >> 1; // 0010
std.debug.print("a & b: {}\n", .{bit_and});
std.debug.print("a | b: {}\n", .{bit_or});
std.debug.print("a ^ b: {}\n", .{bit_xor});
std.debug.print("~a: {}\n", .{bit_not});
std.debug.print("a << 1: {}\n", .{left_shift});
std.debug.print("a >> 1: {}\n", .{right_shift});
}
El resultado de la compilación es:
a & b: 1 a | b: 7 a ^ b: 6 ~a: -6 a << 1: 10 a >> 1: 2
Operadores de asignación
| Operador | Descripción |
|---|---|
| = | Asignación |
| += | Asignación con suma |
| -= | Asignación con resta |
| *= | Asignación con multiplicación |
| /= | Asignación con división |
| %= | Asignación con resto (módulo) |
| &= | Asignación con Y bit a bit |
| |= | Asignación con O bit a bit |
| ^= | Asignación con XOR bit a bit |
| <<= | Asignación con desplazamiento a la izquierda |
| >>= | Asignación con desplazamiento a la derecha |
Ejemplo
pub fn main() void {
var a: i32 = 5;
const b: i32 = 3;
a += b; // Equivale a a = a + b;
std.debug.print("a += b: {}\n", .{a});
a -= b; // Equivale a a = a - b;
std.debug.print("a -= b: {}\n", .{a});
a *= b; // Equivale a a = a * b;
std.debug.print("a *= b: {}\n", .{a});
a = @divTrunc(a, b); // Equivale a a = a / b;
std.debug.print("a /= b: {}\n", .{a});
a = @mod(a, b); // Equivale a a = a % b;
std.debug.print("a %= b: {}\n", .{a});
a &= b; // Equivale a a = a & b;
std.debug.print("a &= b: {}\n", .{a});
a |= b; // Equivale a a = a | b;
std.debug.print("a |= b: {}\n", .{a});
a ^= b; // Equivale a a = a ^ b;
std.debug.print("a ^= b: {}\n", .{a});
a <<= 1; // Equivale a a = a << 1;
std.debug.print("a <<= 1: {}\n", .{a});
a >>= 1; // Equivale a a = a >> 1;
std.debug.print("a >>= 1: {}\n", .{a});
}
El resultado de la compilación es:
a += b: 8 a -= b: 5 a *= b: 15 a /= b: 5 a %= b: 2 a &= b: 2 a |= b: 3 a ^= b: 0 a <<= 1: 0 a >>= 1: 0
Otros operadores
| Operador | Descripción |
|---|---|
| ++ | Incremento |
| -- | Decremento |
Ejemplo
pub fn main() void {
var a: i32 = 5;
a += 1; // Zig no tiene el operador ++, se puede usar += 1 en su lugar
std.debug.print("a += 1: {}\n", .{a});
a -= 1; // Zig no tiene el operador --, se puede usar -= 1 en su lugar
std.debug.print("a -= 1: {}\n", .{a});
}
El resultado de la compilación es:
a += 1: 6 a -= 1: 5
Precedencia de operadores
La siguiente es la lista de precedencia de los operadores de Zig, ordenada de mayor a menor:
| Precedencia | Operador | Descripción |
|---|---|---|
| 1 | [] | Operación de subíndice, acceso a arreglos o punteros |
| 1 | . | Acceso a miembros |
| 2 | fn_call() | Llamada a función |
| 2 | @builtin() | Llamada a función incorporada (built-in) |
| 3 | ! | Propagación de errores |
| 3 | ? | Desempaquetado de valores opcionales |
| 4 | * & | Desreferencia de punteros y operaciones de dirección |
| 5 | + - | Signo positivo y negativo unario |
| 6 | ~ | Complemento bit a bit |
| 7 | * / % | Multiplicación, división, resto |
| 8 | + - | Adición, sustracción |
| 9 | << >> | Desplazamiento bit a bit a la izquierda y a la derecha |
| 10 | & | Y bit a bit |
| 11 | ^ | XOR bit a bit |
| 12 | ` | ` |
| 13 | == != | Igualdad, desigualdad |
| 13 | < <= > >= | Menor que, menor o igual que, mayor que, mayor o igual que |
| 14 | and | Y lógico |
| 15 | or | O lógico |
| 16 | orelse | O devolver otro valor |
| 17 | catch | Capturar errores |
| 18 | = | Asignación |
| 19 | -> | Cuerpo de función de cierre o indicador de tipo de retorno |
Nota:
- Asociatividad: Generalmente, los operadores de Zig son asociativos a la izquierda, pero se puede consultar la documentación según la función específica del operador.
- Notas importantes: El diseño de los operadores en Zig es simple y claro, evitando muchos comportamientos implícitos complejos presentes en otros lenguajes, como la ausencia de conversión de tipos implícita.
El siguiente ejemplo muestra cómo la precedencia de operadores afecta el orden de evaluación de las expresiones:
Ejemplo
pub fn main() void {
const a: i32 = 5;
const b: i32 = 3;
const c: i32 = 2;
// La multiplicación tiene prioridad sobre la suma
const result1: i32 = a + b * c; // 5 + (3 * 2) = 11
std.debug.print("a + b * c = {}\n", .{result1});
// Usar paréntesis para cambiar la precedencia
const result2: i32 = (a + b) * c; // (5 + 3) * 2 = 16
std.debug.print("(a + b) * c = {}\n", .{result2});
// Los operadores de comparación tienen prioridad sobre los operadores lógicos
const result3: bool = a > b and b > c; // (5 > 3) and (3 > 2) = true
std.debug.print("a > b and b > c = {}\n", .{result3});
// La negación lógica tiene prioridad sobre el Y lógico
const result4: bool = !(a > b) and b > c; // !(5 > 3) and (3 > 2) = false
std.debug.print("!(a > b) and b > c = {}\n", .{result4});
}
El resultado de la compilación es:
a + b * c = 11 (a + b) * c = 16 a > b and b > c = true !(a > b) and b > c = falseOtras extensiones