제거됨: 패키지 객체
제거됨: 패키지 객체 (Package Objects)
패키지 객체(package object)는 Scala 3에서 제거될 예정이에요. 아직은 쓸 수 있지만, 언젠가 deprecated가 되고 이후에 제거됩니다.
본문
패키지 객체
package object p {
val a = ...
def b = ...
}
는 제거될 예정이에요. 아직은 사용할 수 있지만, 가까운 미래에 deprecated되고 제거됩니다.
패키지 객체는 이제 더 이상 필요하지 않아요. 모든 종류의 정의를 최상위 레벨(top-level)에 쓸 수 있게 됐기 때문이에요. 예시:
package p
type Labelled[T] = (String, T)
val a: Labelled[Int] = ("count", 1)
def b = a._2
case class C()
extension (x: C) def pair(y: C) = (x, y)
한 패키지 안에 이런 최상위 정의를 담은 소스 파일이 여러 개 있을 수 있고, 소스 파일은 최상위 값·메서드·타입 정의를 클래스나 객체와 자유롭게 섞어 쓸 수 있어요.
컴파일러는 다음 범주에 속하는 최상위 정의를 감싸는 합성 객체(synthetic object)를 만들어내요.
- 모든 패턴, 값, 메서드, 타입 정의
- 암시적 클래스(implicit class)와 객체
- 불투명 타입 별칭(opaque type alias)의 컴패니언 객체
소스 파일 src.scala에 이런 최상위 정의가 있으면, 그 정의들은 src$package라는 이름의 합성 객체에 들어가요. 하지만 이 감싸기는 투명해서, src 안의 정의는 여전히 포함하는 패키지의 멤버로 접근할 수 있어요. 합성 객체는 파일의 다른 패키지 절, 임포트, 객체·클래스 정의보다 뒤인 파일 맨 마지막에 배치됩니다.
참고: 이 말은 즉,
- 감싸인 최상위 정의를 담은 소스 파일의 이름은 바이너리 호환성에 영향을 줘요. 이름이 바뀌면 생성되는 객체와 그 클래스의 이름도 바뀌니까요.
- 최상위
main메서드def main(args: Array[String]): Unit = ...도 다른 메서드처럼 감싸여요. 이 메서드가 소스 파일src.scala에 있으면scala src$package같은 명령으로 커맨드 라인에서 호출할 수 있어요. "프로그램 이름"이 맹글링(mangle)되기 때문에,main메서드는 항상 이름이 명시된 객체에 두는 걸 권장해요. private의 의미는 정의가 감싸였는지와는 무관해요.private최상위 정의는 포함하는 패키지 안 어디에서나 항상 보입니다.- 같은 이름을 가진 여러 최상위 정의가 오버로드된 변형이라면, 반드시 같은 소스 파일에서 와야 해요.