주석

주석 (Comments)

코드를 짜다 보면 "이건 왜 이렇게 했지?" 싶은 순간이 꼭 생기게 마련이에요. 그때 바로 우리를 구해 주는 게 주석인데요, Zig에서 주석은 크게 어떤 자리에 어떤 종류를 쓰느냐가 중요해요. 여기서는 세 가지 주석의 차이와, 각각이 컴파일러에 어떻게 쓰이는지 살펴볼게요.

출처: Zig Documentation

본문

주석에는 세 가지 종류가 있어요. 일반 주석은 그냥 무시되고, Doc CommentsTop-Level Doc Comments는 컴파일러가 패키지 문서를 생성할 때 사용돼요.

comments.zig 파일로 실제 코드를 보면서 시작해 볼게요.

// comments.zig
const print = @import("std").debug.print;

pub fn main() void {
    // Comments in Zig start with "//" and end at the next LF byte (end of line).
    // The line below is a comment and won't be executed.

    //print("Hello?", .{});

    print("Hello, world!\n", .{}); // another comment
}
$ zig build-exe comments.zig
$ ./comments
Hello, world!

흥미로운 점은 Zig에는 멀티라인 주석이 없다는 거예요. 그 대신, Zig는 코드의 각 줄이 독립적으로 토큰화될 수 있는 성질을 가지고 있어요. 그래서 주석이 어디서 시작하는지, 어디서 끝나는지를 항상 명확하게 알 수 있죠.

Doc Comments

Doc comment는 정확히 슬래시 세 개(///이지 ////가 아닌)로 시작하는 주석이에요. 연속으로 여러 개의 doc comment가 있다면 그게 합쳐져서 하나의 멀티라인 doc comment가 돼요. 그리고 이 주석은 바로 뒤에 따라오는 것을 문서화해 줘요.

// doc_comments.zig
/// A structure for storing a timestamp, with nanosecond precision (this is a
/// multiline doc comment).
const Timestamp = struct {
    /// The number of seconds since the epoch (this is also a doc comment).
    seconds: i64, // signed so we can represent pre-1970 (not a doc comment)
    /// The number of nanoseconds past the second (doc comment again).
    nanos: u32,

    /// Returns a `Timestamp` struct representing the Unix epoch; that is, the
    /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).
    pub fn unixEpoch() Timestamp {
        return Timestamp{
            .seconds = 0,
            .nanos = 0,
        };
    }
};

여기서 재미있는 대조가 보이죠? seconds 필드 옆에 붙은 // signed so...는 일반 주석이라서 무시되고, 각 선언 위에 올라간 ///들은 전부 doc comment로 취급돼요.

다만 doc comment는 아무 데나 쓸 수는 없어요. 표현식 중간이라든지, 일반(non-doc) 주석 바로 앞처럼 예상치 못한 자리에 doc comment가 있으면 컴파일 에러가 나요.

// invalid_doc-comment.zig
/// doc-comment
//! top-level doc-comment
const std = @import("std");
$ zig build-obj invalid_doc-comment.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/invalid_doc-comment.zig:1:16: error: expected type expression, found 'a document comment'
/// doc-comment
               ^

unattached_doc-comment.zig처럼 파일 끝에 아무 것도 뒤따르지 않는 doc comment를 남겨도 마찬가지로 에러가 나요.

// unattached_doc-comment.zig
pub fn main() void {}

/// End of file
$ zig build-obj unattached_doc-comment.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/unattached_doc-comment.zig:3:1: error: unattached documentation comment
/// End of file
^~~~~~~~~~~~~~~

그래도 걱정할 건 없어요. doc comment는 일반 주석(무시되는 주석)과 섞여서 자유롭게 배치할 수 있으니까, 설명을 붙이고 싶은 위치에 자연스럽게 끼워 넣으면 돼요.

Top-Level Doc Comments

이번엔 Top-Level Doc Comments예요. 이 주석은 슬래시 두 개에 느낌표가 붙은 //!로 시작하는데, 이 주석은 자신이 포함된 Namespace를 소유하는 타입을 문서화해요.

// tldoc_comments.zig
//! Provides functions for retrieving the current date and time with varying
//! degrees of precision and accuracy.

const S = struct {
    //! Top level comments are allowed inside namespaces other than the
    //! implicit struct created by files, but it is not very useful. Currently,
    //! when producing the package documentation, these comments are ignored.
};

top-level doc comment는 네임스페이스의 시작 부분, 즉 어떤 표현식보다도 앞에 위치해야 해요. 그렇지 않으면 컴파일 에러가 나요. 위 예제의 struct 안에도 //!가 있는 걸 볼 수 있는데, 파일이 만드는 암시적 구조체가 아닌 다른 네임스페이스 안에서는 top-level doc comment가 허용되긴 해요. 다만 지금은 패키지 문서를 생성할 때 이 주석들은 무시되기 때문에 크게 쓸모는 없어요.

더 알아보기

  • Doc Comments: ///로 시작하며 바로 뒤에 오는 것을 문서화하는 주석
  • Top-Level Doc Comments: //!로 시작하며 소유 네임스페이스를 문서화하는 주석
  • Namespace: 문서화의 대상이 되는 네임스페이스 개념