프로그래밍라이브러리 개발자 / Rust 라이브러리 개발자

러스트에서 구조체 필드에 대한 접근 제어는 어떻게 구현되며, 이것이 모듈 가시성과 어떻게 연결되는가? 모듈 밖에서 구조체를 사용할 때 오류를 최소화하기 위해 공개 API를 어떻게 올바르게 구성할 것인가?

Hintsage AI 어시스턴트로 면접 통과

답변.

이야기의 배경:

C++나 Java와 같은 언어에서는 접근 수정자(public, private, protected)가 클래스의 멤버 가시성을 보장하지만, 그 유연성으로 인해 API 사용 시 오류를 예방하지 못하는 경우가 많습니다. 러스트에서는 초기 버전부터 접근 제어 시스템을 엄격하고 모듈화하여 내부 세부정보가 외부로 "유출"되는 것을 제한하고자 했습니다.

문제:

구조체의 일부는 외부 코드로부터 숨겨야 하는 경우가 많습니다. 예를 들어, 필드는 비공개로 설정하고, 외부에는 메서드만 노출합니다. 접근을 제한하지 않으면 구조체의 불변 조건을 의도치 않게 파괴할 수 있습니다(예: 내부 Vec를 직접 노출). 구조체를 무분별하게 공개하면 API가 취약해집니다.

해결책:

러스트에서는 기본적으로 모든 것이 비공개입니다. pub 키워드는 명시적 내보내기 용도로 사용됩니다: 구조체는 별도로 가시화될 수 있고, 필드는 숨길 수 있습니다. 메서드는 각각 pub으로 선언되거나 비공개로 설정됩니다. 또한, pub(crate) 또는 pub(super)와 같은 비표준 형태는 접근 수준을 세밀하게 조정할 수 있게 합니다.

코드 예:

mod domain { pub struct User { pub name: String, age: u32, // 비공개 필드 } impl User { pub fn new(name: String, age: u32) -> Self { Self { name, age } } pub fn age(&self) -> u32 { self.age } } } use domain::User; fn main() { let u = User::new("Eve".to_string(), 24); println!("{} {}", u.name, u.age()); // u.age — 접근 오류! 필드는 모듈 외부에서 닫혀 있음 }

주요 특징:

  • 기본적으로 모든 것이 비공개이며, 필드와 함수도 포함됨
  • pub은 명시적으로 선택된 요소만 외부로 내보냄
  • pub(crate), pub(super)는 대규모 프로젝트에서 접근을 유연하게 조정할 수 있게 함

함정 질문들.

구조체를 pub으로 만들 수 있지만 모든 필드는 비공개로 둘 수 있을까? 그렇다면 모듈 밖에서 어떻게 인스턴스를 생성할 수 있을까?

예. 일반적으로 그렇게 합니다: 구조체는 pub으로 설정하고 필드는 비공개로 두며, 생성은 공개 생성자를 통해서만 가능합니다(예: pub fn new...).

pub struct Foo를 선언할 때 구조체의 필드가 외부 코드에서 보이나?

아니요, 기본적으로 각 필드는 여전히 비공개입니다. 필드에 대해 pub을 명시적으로 적어야 합니다. pub struct는 type만 가시적으로 만듭니다.

enum에 대한 pub도 동일하게 작동하나?

enum에 대한 pub는 모든 변형에 적용되지만, 변형 내의 관련 데이터(예: Variant(value: T) 내의 필드)도 여전히 접근 가능하려면 pub을 명시해야 합니다.

일반적인 실수와 안티 패턴

  • 단순함을 위해 모든 필드를 pub으로 만들어 캡슐화를 위반함
  • 외부 모듈에서 비공개 필드에 직접 접근하려고 시도함(컴파일 오류)
  • 모든 필드가 닫혀 있을 때 구조체를 생성/수정하기 위한 공개 메서드를 만드는 것을 잊음

실제 예

부정적인 사례

라이브러리에서 구조체가 pub struct Config로 선언되었고 모든 필드도 pub으로 설정되어 사용자에게 "보이게" 되었습니다. 결과적으로, 외부 코드가 상태를 임의로 변경할 수 있어 불변 조건을 파괴하고, 아무 이유 없이 panic이 발생할 수 있었습니다.

장점:

  • 사용자에게 최대한의 개방성과 유연성 제공

단점:

  • 캡슐화 위반
  • API의 마이그레이션 및 버전 관리를 어렵게 함
  • 필드의 부적절한 사용으로 인한 버그 증가

긍정적인 사례

구조체 Config는 pub으로 설정하고 모든 필드는 비공개로 두었습니다. 설정은 빌더 메서드, 기본 생성자 또는 setter/getter 함수를 통해서만 이루어집니다. 모듈 밖에서는 불변 조건을 파괴할 수 없습니다.

장점:

  • API가 깔끔하고 불변 조건이 관리됨
  • 이전 버전 호환성 유지가 더 쉬움

단점:

  • 복잡한 구조체의 경우 코드가 더 많이 필요함(메서드, 생성자, 테스트)