연산자

연산자 (Operators)

Zig에는 연산자 오버로딩(operator overloading)이 없어요. 그래서 Zig에서 어떤 연산자를 만나더라도, 그 연산자는 아래 표에 있는 어떤 동작을 수행할 뿐, 그 밖에 다른 일은 하지 않는다는 걸 확실히 알 수 있어요.

출처: Zig Documentation

본문

연산자 표 (Table of Operators)

이름 문법 타입 비고 예제
덧셈 (Addition) a + b
a += b
Integers
Floats
- 정수면 overflow가 날 수 있어요.
- 피연산자에 Peer Type Resolution을 적용해요.
- @addWithOverflow도 함께 봐요.
2 + 5 == 7
래핑 덧셈 (Wrapping Addition) a +% b
a +%= b
Integers - 2의 보수(Twos-complement) 래핑 동작을 해요.
- 피연산자에 Peer Type Resolution을 적용해요.
- @addWithOverflow도 함께 봐요.
@as(u32, 0xffffffff) +% 1 == 0
포화 덧셈 (Saturating Addition) `a + b<br>a + = b` Integers
뺄셈 (Subtraction) a - b
a -= b
Integers
Floats
- 정수면 overflow가 날 수 있어요.
- 피연산자에 Peer Type Resolution을 적용해요.
- @subWithOverflow도 함께 봐요.
2 - 5 == -3
래핑 뺄셈 (Wrapping Subtraction) a -% b
a -%= b
Integers - 2의 보수(Twos-complement) 래핑 동작을 해요.
- 피연산자에 Peer Type Resolution을 적용해요.
- @subWithOverflow도 함께 봐요.
@as(u8, 0) -% 1 == 255
포화 뺄셈 (Saturating Subtraction) `a - b<br>a - = b` Integers
부정 (Negation) -a Integers
Floats
- 정수면 overflow가 날 수 있어요. -1 == 0 - 1
래핑 부정 (Wrapping Negation) -%a Integers - 2의 보수(Twos-complement) 래핑 동작을 해요. -%@as(i8, -128) == -128
곱셈 (Multiplication) a * b
a *= b
Integers
Floats
- 정수면 overflow가 날 수 있어요.
- 피연산자에 Peer Type Resolution을 적용해요.
- @mulWithOverflow도 함께 봐요.
2 * 5 == 10
래핑 곱셈 (Wrapping Multiplication) a *% b
a *%= b
Integers - 2의 보수(Twos-complement) 래핑 동작을 해요.
- 피연산자에 Peer Type Resolution을 적용해요.
- @mulWithOverflow도 함께 봐요.
@as(u8, 200) *% 2 == 144
포화 곱셈 (Saturating Multiplication) `a * b<br>a * = b` Integers
나눗셈 (Division) a / b
a /= b
Integers
Floats
- 정수면 overflow가 날 수 있어요.
- 정수에서 Division by Zero가 날 수 있어요.
- FloatMode.optimized Mode에서는 부동소수점 Division by Zero가 날 수 있어요.
- 부호 있는 정수 피연산자는 comptime-known이고 양수여야 해요. 그 외의 경우엔 @divTrunc, @divFloor, @divCeil 또는 @divExact를 대신 써요.
- 피연산자에 Peer Type Resolution을 적용해요.
10 / 5 == 2
나머지 나눗셈 (Remainder Division) a % b
a %= b
Integers
Floats
- 정수에서 Division by Zero가 날 수 있어요.
- FloatMode.optimized Mode에서는 부동소수점 Division by Zero가 날 수 있어요.
- 부호 있는 정수 또는 부동소수점 피연산자는 comptime-known이고 양수여야 해요. 그 외의 경우엔 @rem 또는 @mod를 대신 써요.
- 피연산자에 Peer Type Resolution을 적용해요.
10 % 3 == 1
왼쪽 비트 시프트 (Bit Shift Left) a << b
a <<= b
Integers - 모든 비트를 왼쪽으로 옮기면서 최하위 비트(least-significant bit)에 새 0을 넣어요.
- bcomptime-known이거나 a의 비트 수를 log2로 한 만큼의 타입이어야 해요.
- @shlExact도 함께 봐요.
- @shlWithOverflow도 함께 봐요.
0b1 << 8 == 0b100000000
포화 왼쪽 비트 시프트 (Saturating Bit Shift Left) `a << b<br>a << = b` Integers
오른쪽 비트 시프트 (Bit Shift Right) a >> b
a >>= b
Integers - LHS가 부호 없으면 **논리 시프트(logical shift)**를 수행해요. 모든 비트를 오른쪽으로 옮기면서 최상위 비트(most-significant bit)에 0을 넣어요.
- LHS가 부호 있으면 **산술 시프트(arithmetic shift)**를 수행해요. 모든 비트를 오른쪽으로 옮기면서, 최상위 비트가 1일 때만 최상위 비트에 1을 넣어요.
- bcomptime-known이거나 a의 비트 수를 log2로 한 만큼의 타입이어야 해요.
- @shrExact도 함께 봐요.
0b1010 >> 1 == 0b101
비트 AND (Bitwise And) a & b
a &= b
Integers - 피연산자에 Peer Type Resolution을 적용해요. 0b011 & 0b101 == 0b001
비트 OR (Bitwise Or) a | b
a |= b
Integers - 피연산자에 Peer Type Resolution을 적용해요. 0b010 | 0b100 == 0b110
비트 XOR (Bitwise Xor) a ^ b
a ^= b
Integers - 피연산자에 Peer Type Resolution을 적용해요. 0b011 ^ 0b101 == 0b110
비트 NOT (Bitwise Not) ~a Integers ~@as(u8, 0b10101111) == 0b01010000
기본값 Optional 언래핑 (Defaulting Optional Unwrap) a orelse b Optionals - anull이면 b("기본값")를 돌려주고, 아니면 a의 언래핑된 값을 돌려줘요.
- bnoreturn 타입의 값일 수도 있어요.
const value: ?u32 = null;
const unwrapped = value orelse 1234;
unwrapped == 1234
Optional 언래핑 (Optional Unwrap) a.? Optionals - a orelse unreachable과 동일해요. const value: ?u32 = 5678;
value.? == 5678
기본값 Error 언래핑 (Defaulting Error Unwrap) a catch b
a catch |err| b
Error Unions - aerrorb("기본값")를 돌려주고, 아니면 a의 언래핑된 값을 돌려줘요.
- bnoreturn 타입의 값일 수도 있어요.
- errerror이고 표현식 b의 스코프 안에 있어요.
const value: anyerror!u32 = error.Broken;
const unwrapped = value catch 1234;
unwrapped == 1234
논리 AND (Logical And) a and b bool - afalseb를 평가하지 않고 false를 돌려줘요. 아니면 b를 돌려줘요. (false and true) == false
논리 OR (Logical Or) a or b bool - atrueb를 평가하지 않고 true를 돌려줘요. 아니면 b를 돌려줘요. (false or true) == true
논리 NOT (Boolean Not) !a bool !false == true
동등 (Equality) a == b Integers
Floats
bool
type
packed struct
- a와 b가 같으면 true, 아니면 false를 돌려줘요.
- 피연산자에 Peer Type Resolution을 적용해요.
(1 == 1) == true
null 검사 (Null Check) a == null Optionals - a가 null이면 true, 아니면 false를 돌려줘요. const value: ?u32 = null;
(value == null) == true
부등 (Inequality) a != b Integers
Floats
bool
type
- a와 b가 같으면 false, 아니면 true를 돌려줘요.
- 피연산자에 Peer Type Resolution을 적용해요.
(1 != 1) == false
non-null 검사 (Non-Null Check) a != null Optionals - a가 null이면 false, 아니면 true를 돌려줘요. const value: ?u32 = null;
(value != null) == false
보다 큼 (Greater Than) a > b Integers
Floats
- a가 b보다 크면 true, 아니면 false를 돌려줘요.
- 피연산자에 Peer Type Resolution을 적용해요.
(2 > 1) == true
크거나 같음 (Greater or Equal) a >= b Integers
Floats
- a가 b보다 크거나 같으면 true, 아니면 false를 돌려줘요.
- 피연산자에 Peer Type Resolution을 적용해요.
(2 >= 1) == true
보다 작음 (Less Than) a < b Integers
Floats
- a가 b보다 작으면 true, 아니면 false를 돌려줘요.
- 피연산자에 Peer Type Resolution을 적용해요.
(1 < 2) == true
작거나 같음 (Lesser or Equal) a <= b Integers
Floats
- a가 b보다 작거나 같으면 true, 아니면 false를 돌려줘요.
- 피연산자에 Peer Type Resolution을 적용해요.
(1 <= 2) == true
배열 결합 (Array Concatenation) a ++ b Arrays - ab의 길이가 둘 다 컴파일 타임에 알려진 경우에만 쓸 수 있어요. const mem = @import("std").mem;
const array1 = [_]u32{1,2};
const array2 = [_]u32{3,4};
const together = array1 ++ array2;
mem.eql(u32, &together, &[_]u32{1,2,3,4})
포인터 역참조 (Pointer Dereference) a.* Pointers - 포인터 역참조를 해요. const x: u32 = 1234;
const ptr = &x;
ptr.* == 1234
주소 취득 (Address Of) &a 모든 타입 (All types) const x: u32 = 1234;
const ptr = &x;
ptr.* == 1234
Error Set 병합 (Error Set Merge) a || b Error Set Type - Merging Error Sets를 수행해요. const A = error{One};
const B = error{Two};
(A || B) == error{One, Two}

우선순위 (Precedence)

우선순위가 높은 연산자가 위에 있어요. 같은 줄에 있는 연산자들은 서로 동일한 우선순위를 가져요.

x() x[] x.y x.* x.?
a!b
x{}
!x -x -%x ~x &x ?x
* / % *% *| ||
+ - ++ +% -% +| -|
<< >> <<|
& ^ | orelse catch
== != < > <= >=
and
or
= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=

더 알아보기

각 연산자가 어떤 타입에서 어떻게 동작하는지, 그리고 그때 넘칠(overflow) 수 있는지는 관련 섹션에서 함께 살펴보면 좋아요. 연산자 표에서 링크로 연결된 Default Operations, Peer Type Resolution, Floating Point Operations, Error Set Type 쪽을 차례로 읽어 보세요.