Rust가 'pub'을 잘못 이해했다
Source: Dev.to

Rust에서 pub 키워드
Rust의 pub 키워드는 접근 제한자이며, 함수, 구조체, 열거형, 트레이트, 모듈과 같은 항목들을 정의된 모듈 밖에서도 접근 가능하게 만든다. 이 점에서 다른 많은 언어의 public과 유사하게 동작한다.
JavaScript/TypeScript와의 비교
특히 JavaScript 배경을 가진 사람들에게 눈에 띄는 큰 차이점은 기본 동작이다.
JS/TS에서는 클래스의 메서드가 기본적으로 public이다(명시적으로 #이나 private 키워드로 표시하지 않는 한). 대부분의 클래스 메서드는 접근 가능해야 한다는 전제가 있기 때문에, 매번 가시성 키워드로 메서드 시그니처를 표시할 필요가 없다. 이를 *구성보다 관습(convention over configuration)*이라고 부를 수 있다.
Rust도 이 아이디어를 차용할 수 있었지만, 정반대로 기본은 private, 명시적으로 선언해야 public이라는 방향을 택했다.
pub의 시각적 잡음
그 결과 다음과 같은 코드가 흔히 보인다:
pub가 여기저기 흩어져 있는 모습이다.
만약 기본 동작이 반대로 되었더라면, Rust가 mut 키워드를 다루는 방식과 비슷하게 더 깔끔한 코드를 얻을 수 있었을 것이다. 변수는 기본적으로 불변이며, mut를 명시하면 해당 값이 나중에 변할 것임을 즉시 알릴 수 있다. 이는 기술적인 의미뿐 아니라 심리적인 신호이기도 하다.
현재 pub는 그런 신호력을 갖지 못한다. 어디에나 나타나 시각적 잡음이 되기 때문이다. Rust가 기본 public을 선택했다면, private를 명시하는 것이 오늘날 mut와 같은 효과를 가졌을 것이다. private 키워드를 보면 독자는 즉시 “이것은 의도적으로 숨겨진 것이며, 의존해서는 안 된다”라고 이해한다.
즉, 코드는 다음과 같이 읽히게 된다:
“여기에 있는 모든 것은 접근 가능하도록 설계되었지만, 이 특정 항목들은 제외한다.”
반면에:
“이것과 이것, 그리고 이것, 그리고 이것을 public으로 만들고 싶다.”
중요한 정정: 모듈 기반 가시성
이 비교가 약간 어색하게 느껴지는 이유를 바로잡아야 한다. Rust의 가시성은 모듈 기반이며, 클래스 기반이 아니다. JavaScript(및 많은 OOP 언어)에서는 가시성이 주로 클래스에 한정된다. Rust에서는 가시성이 모듈에 한정되며, 모듈은 명시적인 API 경계 역할을 한다. 따라서 Rust는 단순히 필드와 메서드를 보호하는 것이 아니라 전체 네임스페이스와 아키텍처 레이어를 보호한다.
따라서 “기본 private” 선택은 단순히 스타일상의 문제가 아니다. 다음을 강력히 장려한다:
- 의도적인 API 설계
- 최소한의 public 표면
- 실수로 인한 파괴적 변경 감소
- 불변성(인variant)의 명확한 소유권
이는 특히 크고 오래 유지되는 시스템 및 라이브러리를 목표로 설계된 언어에서 중요하다.
Rust가 여기서 틀렸다고 할 수 있을까?
아마 그렇지는 않을 것이다. 하지만 사용성 논쟁이 타당하지 않다고 할 수는 없다. 확실히 그렇다.
Rust는 정확성과 안정성을 위해 가독성을 희생한다. 이 선택은 언어 설계 관점에서는 타당하지만, 특히 JS/TS 배경을 가진 사람들에게는 public API가 암시적으로 존재하고 선언되지 않는 경우가 많기 때문에 가독성 비용이 발생한다.
이 트레이드오프가 가치 있는지는 무엇을 더 중시하느냐에 달려 있다:
- 시각적 깔끔함
- 혹은 타협 없는 명시성
Rust는 분명 후자를 선택했다.
