- Zig는 Rust와 비슷한 중괄호 기반 문법을 기반으로 하지만, 더 단순한 언어 의미와 세련된 문법 선택으로 개선함
- 정수 리터럴은 모든 타입이
comptime_int로 시작해 할당 시 명시적으로 변환되며, 문자열 리터럴은 \\ 기반의 간결한 원시 문자열 표기법을 사용함
.x = 1 형태의 레코드 리터럴은 필드 쓰기를 쉽게 검색 가능하게 하며, 모든 타입은 접두사 표기법으로 일관성 있게 표현됨
and·or를 제어 흐름 키워드로 사용하고, if·loop 구문은 선택적으로 중괄호를 생략할 수 있으며 포맷터가 안전성을 보장함
- 네임스페이스 없이 모든 것을 표현식으로 처리해 타입·값·패턴 문법을 통합하고, 제네릭·레코드 리터럴·내장 함수(
@import, @as 등)를 간결하게 활용함
개요
- Zig는 Rust와 유사한 외형을 가지지만 더 단순한 언어 구조를 채택
- 문법 설계에서 grep 친화성, 구문 일관성, 불필요한 시각적 잡음 감소에 집중
정수 리터럴
const an_integer = 92;
assert(@TypeOf(an_integer) == comptime_int);
const x: i32 = 92;
const y = @as(i32, 92);
- 모든 정수 리터럴은
comptime_int 타입
- 변수에 할당 시 명시적으로 타입을 지정하거나
@as를 사용해 변환
var x = 92; 형태는 작동하지 않으며 명시적 타입 필요
문자열 리터럴
const raw =
\\Roses are red
\\ Violets are blue,
\\Sugar is sweet
\\ And so are you.
\\
;
- 각 행이 개별 토큰이라 들여쓰기 문제가 없음
\\ 자체를 이스케이프할 필요 없음
레코드 리터럴
const p: Point = .{
.x = 1,
.y = 2,
};
.x = 1 형식은 읽기/쓰기 구분에 유리
.{} 표기는 블록과 구분하면서 결과 타입으로 자동 변환
타입 표기법
u32 // 정수
[3]u32 // 길이 3 배열
?[3]u32 // null 가능 배열
*const ?[3]u32 // 상수 포인터
- 모든 타입은 접두사(prefix) 표기
- 역참조는 접미사 표기(
ptr.*)
식별자
const @"a name with space" = 42;
함수 선언
pub fn main() void {}
fn add(x: i32, y: i32) i32 {
return x + y;
}
fn 키워드와 함수명이 붙어 있어 검색이 용이
- 반환 타입 표기에
->를 쓰지 않음
변수 선언
const mid = lo + @divFloor(hi - lo, 2);
var count: u32 = 0;
const와 var 사용
- 타입 표기는
이름: 타입 순서
제어 흐름: and/or
while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {
count -= 1;
}
and, or는 제어 흐름 키워드
- 비트 연산에는
&, | 사용
if 문
.direction = if (prng.boolean()) .ascending else .descending;
- 괄호 필수, 중괄호 선택
zig fmt가 안전한 포맷 보장
반복문
for (0..10) |i| {
print("{d}\n", .{i});
} else @panic("loop safety counter exceeded");
for, while 모두 else 절 지원
- 반복자와 요소명을 직관적으로 배치
네임스페이스와 이름 해석
const std = @import("std");
const ArrayList = std.ArrayList;
- 변수 섀도잉 금지
- 네임스페이스와 글롭 임포트 없음
모든 것은 표현식
const E = enum { a, b };
const e: if (true) E else void = .a;
- 타입·값·패턴 구문을 통합
- 타입 위치에 조건식을 둘 수 있음
제네릭
fn ArrayListType(comptime T: type) type {
return struct {
fn init() void {}
};
}
var xs: ArrayListType(u32) = .init();
- 제네릭은 함수 호출 구문(
Type(T))으로 표현
- 타입 인자는 항상 명시
내장 함수
const foo = @import("./foo.zig");
const num = @as(i32, 92);
@ 접두사로 컴파일러 제공 기능 호출
@import는 파일 경로를 명확히 표시
- 인자는 반드시 문자열 리터럴이어야 함
결론
- Zig 문법은 작은 선택들의 집합이 모여 읽기 좋은 언어를 만든 사례
- 기능 수를 줄이면 필요한 문법도 줄어들고, 구문 간 충돌 가능성도 감소
- 기존 언어의 좋은 아이디어를 차용하되, 필요할 때는 과감히 새 문법을 도입