프렐류드
프렐류드 (Preludes)
Rust 코드를 쓰다 보면 Vec이나 Box 같은 이름을 use 없이 바로 쓰게 돼요. 이게 가능한 이유가 바로 프렐류드(prelude)예요. 어떤 이름들이 자동으로 스코프에 들어오는지, 그 규칙을 이 페이지에서 정리해볼게요.
출처: Rust Reference
본문
**프렐류드(prelude)**는 크레이트의 모든 모듈로 자동으로 스코프에 들어오는 이름들의 모음이에요. 이 프렐류드 이름들은 모듈 자체의 일부가 아니에요. 이름 분석 중에 암묵적으로 조회되죠. 예를 들어 Box 같은 것이 모든 모듈에서 스코프에 있더라도, 현재 모듈의 멤버가 아니기 때문에 self::Box로는 참조할 수 없어요.
프렐류드에는 여러 종류가 있어요.
- 표준 라이브러리 프렐류드 (Standard library prelude)
- 외부 프렐류드 (Extern prelude)
- 언어 프렐류드 (Language prelude)
macro_use프렐류드- 도구 프렐류드 (Tool prelude)
표준 라이브러리 프렐류드
각 크레이트는 표준 라이브러리 프렐류드를 가지는데, 이는 단일 표준 라이브러리 모듈의 이름들로 구성돼요. 사용되는 모듈은 크레이트의 에디션(edition)과, 크레이트에 no_std 속성이 적용되었는지 여부에 따라 달라져요.
| 에디션 | no_std 미적용 |
no_std 적용 |
|---|---|---|
| 2015 | std::prelude::rust_2015 |
core::prelude::rust_2015 |
| 2018 | std::prelude::rust_2018 |
core::prelude::rust_2018 |
| 2021 | std::prelude::rust_2021 |
core::prelude::rust_2021 |
| 2024 | std::prelude::rust_2024 |
core::prelude::rust_2024 |
참고:
std::prelude::rust_2015와std::prelude::rust_2018은std::prelude::v1과 내용이 같아요.core::prelude::rust_2015와core::prelude::rust_2018도core::prelude::v1과 내용이 같아요.
참고: 표준 라이브러리 프렐류드 때문에
core::panic!또는std::panic!중 하나가 스코프에 들어오고, 사용자가 작성한 글롭 임포트가 다른 하나를 스코프에 들여올 때,panic!은 모호함에도 불구하고 현재 rustc는 그 사용을 허용해요. 사용자가 작성한 글롭 임포트가 우선하여 이 모호성을 해결해요.
외부 프렐류드 (Extern prelude)
루트 모듈에서 extern crate로 임포트하거나 (rustc의 --extern 플래그처럼) 컴파일러에 제공된 외부 크레이트들은 외부 프렐류드에 추가돼요. extern crate orig_name as new_name처럼 별칭으로 임포트하면, 대신 new_name 심볼이 프렐류드에 추가돼요.
core 크레이트는 항상 외부 프렐류드에 추가돼요. std 크레이트는 크레이트 루트에 no_std 속성이 지정되지 않는 한 추가돼요.
2018 에디션 차이
2015 에디션에서는 외부 프렐류드의 크레이트를 use 선언으로 참조할 수 없어서, 보통 extern crate 선언을 포함해 이들을 스코프로 가져오는 것이 일반적인 관례였어요. 2018 에디션부터는 use 선언이 외부 프렐류드의 크레이트를 참조할 수 있으므로, extern crate를 쓰는 것은 비관용적(unidiomatic)으로 간주돼요.
참고:
alloc,test처럼 rustc와 함께 배포되는 추가 크레이트들은 Cargo를 사용할 때--extern플래그에 자동으로 포함되지 않아요. 2018 에디션에서도extern crate선언으로 스코프에 가져와야 해요.
extern crate alloc;
use alloc::rc::Rc;
Cargo는 proc-macro 크레이트에 대해서만 proc_macro를 외부 프렐류드로 가져와요.
no_std 속성
no_std 속성은 std 크레이트가 자동으로 링크되지 않게 하고, 대신 표준 라이브러리 프렐류드가 core 프렐류드를 사용하도록 해요.
#![no_std]
참고:
no_std를 쓰는 것은 크레이트가 표준 라이브러리를 지원하지 않는 플랫폼을 대상으로 하거나, 의도적으로 표준 라이브러리의 기능을 사용하지 않을 때 유용해요. 그 기능은 주로 동적 메모리 할당 (예:Box,Vec)과 파일·네트워크 기능 (예:std::fs,std::io)이에요.
경고:
no_std를 쓴다고 표준 라이브러리가 링크되지 않는 것은 아니에요. 크레이트나 그 의존성 중 하나에서extern crate std를 쓰는 것은 여전히 유효하며, 이는 컴파일러가std크레이트를 프로그램에 링크하게 만들어요.
no_std 속성은 MetaWord 문법을 사용해요. 크레이트 루트에만 적용할 수 있고, 한 형태에 몇 번이든 사용할 수 있어요. (rustc는 첫 사용 이후의 사용에 대해 린트를 걸어요.) no_std 속성은 표준 라이브러리 프렐류드가 std 프렐류드 대신 core 프렐류드를 사용하도록 바꿔요.
2018 에디션 차이
2018 에디션 이전에는 std가 기본적으로 크레이트 루트에 주입됐어요. no_std가 지정되면 대신 core가 주입됐죠. 2018 에디션부터는 no_std 지정 여부와 무관하게 둘 다 크레이트 루트에 주입되지 않아요.
언어 프렐류드 (Language prelude)
언어 프렐류드는 언어에 내장된 타입과 속성의 이름을 포함해요. 언어 프렐류드는 항상 스코프에 있어요. 여기에는 다음이 포함돼요.
타입 네임스페이스
- 부울 타입 —
bool charstr- 정수 타입 —
i8,i16,i32,i64,i128,u8,u16,u32,u64,u128 - 기계 의존 정수 타입 —
usize,isize - 부동소수점 타입 —
f32,f64
매크로 네임스페이스
- 내장 속성 (Built-in attributes)
- 내장 derive 매크로
macro_use 프렐류드
macro_use 프렐류드는 extern crate에 적용된 macro_use 속성으로 임포트된 외부 크레이트의 매크로들을 포함해요.
도구 프렐류드 (Tool prelude)
도구 프렐류드는 타입 네임스페이스에서 외부 도구들의 도구 이름을 포함해요. 자세한 내용은 도구 속성 섹션에서 볼 수 있어요.
no_implicit_prelude 속성
no_implicit_prelude 속성은 암묵적 프렐류드들이 스코프로 들어오지 않게 막는 데 사용돼요.
// 이 속성을 크레이트 루트에 적용하면 모든 모듈에 영향.
#![no_implicit_prelude]
// 또는 모듈에 적용하면 그 모듈과 하위 모듈에만 영향.
#[no_implicit_prelude]
mod example {
// ...
}
no_implicit_prelude 속성은 MetaWord 문법을 사용해요. 크레이트나 모듈에만 적용할 수 있어요. (다른 위치에서의 use는 rustc가 무시하지만 린트를 걸어요. 이는 미래에 오류가 될 수 있어요.) 한 형태에 몇 번이든 사용할 수 있어요. (rustc는 첫 사용 이후의 사용에 대해 린트를 걸어요.)
no_implicit_prelude 속성은 해당 모듈과 하위 모듈에 대해 표준 라이브러리 프렐류드, 외부 프렐류드, macro_use 프렐류드, 도구 프렐류드가 스코프로 들어오지 않게 막아요.
참고:
#![no_implicit_prelude]에도 불구하고, rustc는 현재 특정 매크로들을 암묵적으로 스코프로 가져와요. 그 매크로들은 다음과 같아요:assert!,cfg!,cfg_select!,column!,compile_error!,concat!,concat_bytes!,env!,file!,format_args!,include!,include_bytes!,include_str!,line!,module_path!,option_env!,panic!,stringify!,unreachable!.예를 들어 이건 동작해요:
#![no_implicit_prelude] fn main() { assert!(true); }이 동작에 의존하지 마세요. 미래에 제거될 수 있어요.
#![no_implicit_prelude]를 쓸 때는 항상 필요한 아이템들을 명시적으로 스코프에 가져오세요.
no_implicit_prelude 속성은 언어 프렐류드에는 영향을 주지 않아요.
2018 에디션 차이
2015 에디션에서 no_implicit_prelude 속성은 macro_use 프렐류드에 영향을 주지 않고, 표준 라이브러리에서 내보낸 모든 매크로가 여전히 macro_use 프렐류드에 포함됐어요. 2018 에디션부터는 이 속성이 macro_use 프렐류드를 제거해요.
더 알아보기 (Learn more)
- Rust Reference의 프렐류드 문서에서 전체 내용을 확인할 수 있어요.
- Rust Reference의 이름 분석 문서에서 프렐류드가 어떻게 조회되는지 더 자세히 다룬답니다.
- Rust Reference의 no_std 관련 크레이트 문서를 통해 표준 라이브러리 없이 개발하는 방법을 살펴볼 수 있어요.