Vamos dar continuidade a nossa Série sobre Zig!
Na postagem anterior vimos:
E nessa postagem veremos:
Assim como em outras linguagens de programação, os operadores em Zig são usados para executar operações em variáveis e valores. São eles:
Categoria | Operador | Descrição | |
---|---|---|---|
Aritméticos | + |
Soma | |
- |
Subtração | ||
* |
Multiplicação | ||
/ |
Divisão inteira (com erro em divisão por zero) | ||
divTrunc |
Divisão truncada (não lança erro) | ||
divFloor |
Divisão com arredondamento para -∞ | ||
% |
Resto (mod) | ||
mod |
Módulo matemático (resultado sempre positivo) | ||
** |
Potência | ||
Incremento/Decr. | += |
Soma e atribuição | |
-= |
Subtração e atribuição | ||
*= |
Multiplicação e atribuição | ||
/= |
Divisão e atribuição | ||
Bitwise | & |
AND bit a bit | |
` | ` | OR bit a bit | ||
^ |
XOR bit a bit | ||
~ |
NOT bit a bit | ||
<< |
Shift à esquerda | ||
>> |
Shift à direita | ||
&= |
AND e atribuição | ||
` | =` | OR e atribuição | ||
^= |
XOR e atribuição | ||
<<= |
Shift à esquerda e atribuição | ||
>>= |
Shift à direita e atribuição | ||
Comparação | == |
Igualdade | |
!= |
Diferença | ||
< |
Menor | ||
<= |
Menor ou igual | ||
> |
Maior | ||
>= |
Maior ou igual | ||
Lógicos | ! |
NOT lógico | |
and |
AND lógico | ||
or |
OR lógico | ||
Outros | ? |
Operador de erro (unwrap / try / catch) | |
try |
Propaga erro | ||
catch |
Trata erro | ||
orelse |
Valor padrão em caso de null ou erro |
||
if |
Condicional | ||
else |
Alternativa ao if |
||
while , for |
Laços | ||
break , continue , return |
Controle de fluxo | ||
Pointer/Deref. | * |
Dereferência | |
& |
Referência (endereço) | ||
. |
Acesso a campo | ||
-> |
Acesso a campo de ponteiro (via .* ) |
||
Array/Slice | [] |
Indexação | |
len |
Tamanho (.len ) |
||
Struct/Enum/Union | @field |
Acesso dinâmico a campo | |
@enumToInt |
Enum para inteiro | ||
@intToEnum |
Inteiro para enum |
Zig não tem sobrecarga de operadores nem operadores customizáveis.
Zig, lógico, também suporta condições lógicas e declarações:
if
e else
const std = @import("std");
pub fn main() void {
const x = 10;
if (x > 5) {
std.debug.print("maior que 5\n", .{});
} else {
std.debug.print("menor ou igual a 5\n", .{});
}
}
if
exige valor booleano.if
como expressãoconst result = if (true) 1 else 2;
// result == 1
if
com orelse
(para opcionais)const maybe_num: ?i32 = null;
const val = maybe_num orelse 42; // se null, usa 42
if
com catch
(para erros)fn mightFail() !i32 {
return error.Fail;
}
const result = mightFail() catch 123;
// se erro, usa 123
switch
const std = @import("std");
pub fn main() void {
const value = 2;
switch (value) {
1 => std.debug.print("um\n", .{}),
2 => std.debug.print("dois\n", .{}),
else => std.debug.print("outro\n", .{}),
}
}
switch
exige exaustividade ou else
.const name = switch (value) {
1 => "um",
2 => "dois",
else => "outro",
};
if
com optional
+ if
const opt: ?i32 = 5;
if (opt) |val| {
// val contém o valor não-nulo
std.debug.print("Valor: {}\n", .{val});
} else {
std.debug.print("É null\n", .{});
}
if
com error union
fn f() !i32 {
return 5;
}
if (f()) |val| {
std.debug.print("Sem erro: {}\n", .{val});
} else |err| {
std.debug.print("Erro: {}\n", .{err});
}
Na programação estruturada, loop ou laço é um recurso para executar determinadas ações até que a condição seja satisfatória. No caso do comando loop ou laço seletivo que o torna possível o local e o momento que será usado em um programa para a verificação da condição de encerramento do mesmo.
Abaixo estão todos os tipos de loops em Zig, com exemplos objetivos:
while
var i: i32 = 0;
while (i < 5) : (i += 1) {
std.debug.print("i = {}\n", .{i});
}
: (i += 1)
é o incremento (opcional).for
clássico de C.while
com break
e continue
var i: i32 = 0;
while (true) {
if (i == 3) {
i += 1;
continue; // pula o restante do loop
}
if (i >= 5) break;
std.debug.print("{}\n", .{i});
i += 1;
}
while
com binding (opcional)const opt: ?i32 = 10;
while (opt) |val| {
std.debug.print("val = {}\n", .{val});
break;
}
while
com errofn maybeFail(i: i32) !i32 {
if (i == 3) return error.Fail;
return i;
}
var i: i32 = 0;
while (maybeFail(i)) |val| : (i += 1) {
std.debug.print("val = {}\n", .{val});
}
for
com arrays/slicesconst arr = [_]i32{1, 2, 3};
for (arr) |val| {
std.debug.print("val = {}\n", .{val});
}
|val|
é o valor do elemento.for (arr) |val, i| {
std.debug.print("arr[{}] = {}\n", .{i, val});
}
for
com break/continuefor (arr) |val| {
if (val == 2) continue;
if (val == 3) break;
std.debug.print("val = {}\n", .{val});
}
inline for
(comptime)const std = @import("std");
const arr = [_]i32{1, 2, 3};
pub fn main() void {
inline for (arr) |val| {
std.debug.print("Comptime val = {}\n", .{val});
}
}
loop
com rótulo (label) para controle aninhadoouter: while (true) {
inner: while (true) {
break :outer; // quebra o loop externo
}
}
while
com condiçãovar i: i32 = 0;
while (i < 5) : (i += 1) {
std.debug.print("{}\n", .{i});
}
while
com optional bindingconst arr = [_]?i32{ 1, 2, null, 4 };
var i: usize = 0;
while (i < arr.len) : (i += 1) {
if (arr[i]) |val| {
std.debug.print("Valor: {}\n", .{val});
} else {
std.debug.print("Null\n", .{});
}
}
Até o próximo artigo!