러스트에서 가시성 수정자는 모듈의 요소(구조체, 함수, 상수 등)에 대한 접근을 관리합니다. 기본적으로 모듈에서 선언된 모든 것은 비공개(private)입니다(해당 모듈 내에서만 접근 가능). 특별한 수정자가 존재합니다:
pub: 요소를 공개적으로 만들어서 모든 외부 모듈에서 볼 수 있게 합니다.pub(crate): 가시성을 현재 crate(패키지)로 제한합니다.pub(super): 가시성을 상위 모듈로 제한합니다.pub(in path): 특정 경로로 가시성을 제한합니다.예시:
mod foo { pub struct Bar { pub x: i32, // 필드는 어디서나 접근 가능 y: i32, // 필드는 비공개 } pub(crate) fn crate_fn() {} pub(super) fn super_fn() {} fn private_fn() {} }
C++이나 자바와의 주요 차이점은 protected와 같은 별도의 수준이 없으며, 접근 가능성은 클래스 계층이 아니라 모듈/경로 수준에서 엄격하게 통제된다는 점입니다.
질문: 구조체가 pub struct Foo로 선언되면, 다른 모듈에서 그 비공개 필드에 접근할 수 있나요?
보통의 대답: 네, 구조체가 공개적이니까요.
정답: 아니요, 구조체(Foo)만이 가시성이 있을 것이고, 필드는 pub 수정자로 선언된 경우에만 접근 가능해집니다. pub 없이 선언된 필드는 비공개로 남아 있습니다, 비록 구조체 자체는 공개적일지라도.
예시:
mod foo { pub struct Bar { pub x: i32, y: i32, } } fn main() { let bar = foo::Bar { x: 1, y: 2 }; // 오류: 필드 `y`에 접근할 수 없음 }
사례
대규모 프로젝트에서 구조체를 pub을 통해 공개적으로 내보냈지만, 필드는 기본적으로 비공개로 설정되었습니다. 다른 모듈은 구조체의 인스턴스를 직접 생성할 수 없었고, 유일한 해결책은 추가 생성자를 작성하거나 필요한 필드를 pub으로 선언하는 것이었습니다. 이는 API를 최종적으로 완성하기 전까지 중단하였습니다.
사례
라이브러리에서 한 개발자는 함수에 단지 pub(crate)만 사용하며 이 라이브러리를 사용하는 바이너리 프로젝트에서 호출이 가능하다고 생각했습니다. 하지만 이러한 함수는 외부 바이너리 crate에서 접근할 수 없게 되어 통합시 문제가 발생했습니다.
사례
API 서버의 하나의 플러그인에서 구조체에 pub(super)를 사용했으나, 시간이 지나면서 다른 모듈에서 접근할 필요가 생겼고; 가시성 설정 때문에 여러 곳에서 모듈을 상당히 다시 작성해야 할 상황이 발생했습니다.