주석
주석 (Comments)
코드를 읽는 사람과 소통하는 가장 쉬운 방법, 주석이에요. Rust의 주석은 크게 일반 주석(non-doc comment) 과 문서 주석(doc comment) 으로 나뉘어요. 각각 언제 어떻게 쓰는지, 그리고 컴파일러가 어떻게 해석하는지 정리해 볼게요.
출처: Rust Reference
본문
문법 (Syntax)
COMMENT → LINE_COMMENT
| INNER_LINE_DOC
| OUTER_LINE_DOC
| INNER_BLOCK_DOC
| OUTER_BLOCK_DOC
| BLOCK_COMMENT
LINE_COMMENT → // ( ~[/ ! [LF]] | // ) ~[LF]*
| // [EOF]
| // immediately followed by LF
BLOCK_COMMENT → /* ^ ( BLOCK_COMMENT_OR_DOC | ( !*/ [CHAR] ) )* */
INNER_LINE_DOC → //! ^ LINE_DOC_COMMENT_CONTENT ( [LF] | [EOF] )
LINE_DOC_COMMENT_CONTENT → ( ![CR] ~[LF] )*
INNER_BLOCK_DOC → /*! ^ ( BLOCK_COMMENT_OR_DOC | BLOCK_CHAR )* */
OUTER_LINE_DOC → /// ^ LINE_DOC_COMMENT_CONTENT ( [LF] | [EOF] )
OUTER_BLOCK_DOC → /** ![* /] ^
( ~* | BLOCK_COMMENT_OR_DOC )
( BLOCK_COMMENT_OR_DOC | BLOCK_CHAR )* */
BLOCK_CHAR → ( !( */ | [CR] ) [CHAR] )
BLOCK_COMMENT_OR_DOC → INNER_BLOCK_DOC | OUTER_BLOCK_DOC | BLOCK_COMMENT
일반 주석 (Non-doc comments)
일반 주석은 C++ 스타일의 한 줄 주석(//) 과 블록 주석(/* ... */) 형태를 따르고, 블록 주석의 중첩(nested block comments) 을 지원해요.
#![allow(unused)]
fn main() {
// 한 줄 주석
/* 블록 주석 */
/* 중첩도 /* 가능해요 */ */
}
일반 주석은 공백(whitespace)의 한 형태로 해석돼요. 즉 토큰을 구분하는 역할만 하고, 컴파일 결과에 아무 영향을 주지 않아요.
문서 주석 (Doc comments)
바깥 문서 주석(outer doc comments) 은 정확히 슬래시 세 개(///)로 시작하는 한 줄 문서 주석과 블록 문서 주석(/** ... */)이에요. 이것들은 doc 속성을 위한 특별한 문법으로 해석돼요.
즉, 주석 본문을 #[doc="..."] 로 감싼 것과 동일해요. 예를 들어 /// Foo 는 #[doc=" Foo"] 가 되고, /** Bar */ 는 #[doc=" Bar "] 가 돼요. 따라서 바깥 속성(outer attribute)을 받을 수 있는 무언가 앞에 나타나야 해요.
반면 //! 로 시작하는 한 줄 주석과 /*! ... */ 블록 주석은 안쪽 문서 주석(inner doc comments) 으로, 뒤에 오는 아이템이 아니라 주석의 부모에 적용돼요. 이건 #![doc="..."] 로 감싼 것과 동일하죠. //! 주석은 보통 하나의 소스 파일을 차지하는 모듈을 문서화할 때 써요.
문서 주석에서는 U+000D(CR) 문자를 사용할 수 없어요.
참고 1: 관례상 문서 주석은
rustdoc이 기대하듯 Markdown을 담아요. 하지만 주석 문법 자체는 내부의 Markdown을 해석하지 않아요. 예를 들어/**glob = "/.rs";*/처럼 쓰면 첫 번째*/에서 주석이 끝나 버려서, 남은 코드가 문법 오류가 돼요. 그래서 블록 문서 주석은 한 줄 문서 주석보다 담을 수 있는 내용이 조금 제약돼요.
참고 2:
U+000D(CR) 바로 뒤에U+000A(LF)가 오는 시퀀스는 이전에 하나의U+000A(LF)로 변환되곤 했어요.
예시 (Examples)
다음 예시로 주석 종류를 한눈에 확인할 수 있어요.
#![allow(unused)]
fn main() {
//! A doc comment that applies to the implicit anonymous module of this crate
pub mod outer_module {
//! - Inner line doc
//!! - Still an inner line doc (but with a bang at the beginning)
/*! - Inner block doc */
/*!! - Still an inner block doc (but with a bang at the beginning) */
// - Only a comment
/// - Outer line doc (exactly 3 slashes)
//// - Only a comment
/* - Only a comment */
/** - Outer block doc (exactly) 2 asterisks */
/*** - Only a comment */
pub mod inner_module {}
pub mod nested_comments {
/* In Rust /* we can /* nest comments */ */ */
// All three types of block comments can contain or be nested inside
// any other type:
/* /* */ /** */ /*! */ */
/*! /* */ /** */ /*! */ */
/** /* */ /** */ /*! */ */
pub mod dummy_item {}
}
pub mod degenerate_cases {
// empty inner line doc
//!
// empty inner block doc
/*!*/
// empty line comment
//
// empty outer line doc
///
// empty block comment
/**/
pub mod dummy_item {}
// empty 2-asterisk block isn't a doc block, it is a block comment
/***/
}
/* The next one isn't allowed because outer doc comments
require an item that will receive the doc */
/// Where is my item?
mod boo {}
}
}
여기서 핵심만 짚어 볼게요.
- 슬래시가 정확히 3개 (
///)여야 바깥 문서 주석, 4개(////)면 그냥 주석이에요. - 별표가 정확히 2개 (
/**)여야 바깥 블록 문서 주석, 3개(/***)면 그냥 주석이에요. /*!나//!는 안쪽 문서 주석이라, 모듈처럼 부모 항목에 붙어요.- 블록 주석은 서로 다른 종류끼리도 자유롭게 중첩될 수 있어요.
- 바깥 문서 주석(
///)은 문서를 받을 아이템이 반드시 뒤에 필요해요. 예시 마지막에 있는/// Where is my item?처럼 아이템 없이 쓰면 안 돼요.
더 알아보기 (Learn more)
- 속성 (Attributes) — 문서 주석이 실제로 변환되는
doc속성 - 아이템 (Items) — 문서 주석이 붙는 선언들
- rustdoc — 문서 주석으로 문서를 만드는 도구