연산자
연산자 (Operators)
Zig에는 연산자 오버로딩(operator overloading)이 없어요. 그래서 Zig에서 어떤 연산자를 만나더라도, 그 연산자는 아래 표에 있는 어떤 동작을 수행할 뿐, 그 밖에 다른 일은 하지 않는다는 걸 확실히 알 수 있어요.
본문
연산자 표 (Table of Operators)
| 이름 | 문법 | 타입 | 비고 | 예제 |
|---|---|---|---|---|
| 덧셈 (Addition) | a + ba += b |
Integers Floats |
- 정수면 overflow가 날 수 있어요. - 피연산자에 Peer Type Resolution을 적용해요. - @addWithOverflow도 함께 봐요. |
2 + 5 == 7 |
| 래핑 덧셈 (Wrapping Addition) | a +% ba +%= b |
Integers | - 2의 보수(Twos-complement) 래핑 동작을 해요. - 피연산자에 Peer Type Resolution을 적용해요. - @addWithOverflow도 함께 봐요. |
@as(u32, 0xffffffff) +% 1 == 0 |
| 포화 덧셈 (Saturating Addition) | `a + | b<br>a + |
= b` | Integers |
| 뺄셈 (Subtraction) | a - ba -= b |
Integers Floats |
- 정수면 overflow가 날 수 있어요. - 피연산자에 Peer Type Resolution을 적용해요. - @subWithOverflow도 함께 봐요. |
2 - 5 == -3 |
| 래핑 뺄셈 (Wrapping Subtraction) | a -% ba -%= 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 * ba *= b |
Integers Floats |
- 정수면 overflow가 날 수 있어요. - 피연산자에 Peer Type Resolution을 적용해요. - @mulWithOverflow도 함께 봐요. |
2 * 5 == 10 |
| 래핑 곱셈 (Wrapping Multiplication) | a *% ba *%= b |
Integers | - 2의 보수(Twos-complement) 래핑 동작을 해요. - 피연산자에 Peer Type Resolution을 적용해요. - @mulWithOverflow도 함께 봐요. |
@as(u8, 200) *% 2 == 144 |
| 포화 곱셈 (Saturating Multiplication) | `a * | b<br>a * |
= b` | Integers |
| 나눗셈 (Division) | a / ba /= 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 % ba %= 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 << ba <<= b |
Integers | - 모든 비트를 왼쪽으로 옮기면서 최하위 비트(least-significant bit)에 새 0을 넣어요. - b는 comptime-known이거나 a의 비트 수를 log2로 한 만큼의 타입이어야 해요.- @shlExact도 함께 봐요. - @shlWithOverflow도 함께 봐요. |
0b1 << 8 == 0b100000000 |
| 포화 왼쪽 비트 시프트 (Saturating Bit Shift Left) | `a << | b<br>a << |
= b` | Integers |
| 오른쪽 비트 시프트 (Bit Shift Right) | a >> ba >>= b |
Integers | - LHS가 부호 없으면 **논리 시프트(logical shift)**를 수행해요. 모든 비트를 오른쪽으로 옮기면서 최상위 비트(most-significant bit)에 0을 넣어요. - LHS가 부호 있으면 **산술 시프트(arithmetic shift)**를 수행해요. 모든 비트를 오른쪽으로 옮기면서, 최상위 비트가 1일 때만 최상위 비트에 1을 넣어요. - b는 comptime-known이거나 a의 비트 수를 log2로 한 만큼의 타입이어야 해요.- @shrExact도 함께 봐요. |
0b1010 >> 1 == 0b101 |
| 비트 AND (Bitwise And) | a & ba &= b |
Integers | - 피연산자에 Peer Type Resolution을 적용해요. | 0b011 & 0b101 == 0b001 |
| 비트 OR (Bitwise Or) | a | ba |= b |
Integers | - 피연산자에 Peer Type Resolution을 적용해요. | 0b010 | 0b100 == 0b110 |
| 비트 XOR (Bitwise Xor) | a ^ ba ^= 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 | - a가 null이면 b("기본값")를 돌려주고, 아니면 a의 언래핑된 값을 돌려줘요.- b는 noreturn 타입의 값일 수도 있어요. |
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 ba catch |err| b |
Error Unions | - a가 error면 b("기본값")를 돌려주고, 아니면 a의 언래핑된 값을 돌려줘요.- b는 noreturn 타입의 값일 수도 있어요.- err는 error이고 표현식 b의 스코프 안에 있어요. |
const value: anyerror!u32 = error.Broken;const unwrapped = value catch 1234;unwrapped == 1234 |
| 논리 AND (Logical And) | a and b |
bool | - a가 false면 b를 평가하지 않고 false를 돌려줘요. 아니면 b를 돌려줘요. |
(false and true) == false |
| 논리 OR (Logical Or) | a or b |
bool | - a가 true면 b를 평가하지 않고 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 | - a와 b의 길이가 둘 다 컴파일 타임에 알려진 경우에만 쓸 수 있어요. |
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 쪽을 차례로 읽어 보세요.