126
1
부
스칼라와의 만남
CAUTION
_
스칼라에서는 스크립트 안에서 패키지를 선언하지 못한다. 스크립트는 암시적으로 객체로 싸
여 있고, 객체 안에서는 패키지를 선언할 수 없다.
2.12
타입과 멤버 임포트하기
패키지 안에 들어 있는 선언을 사용하기 위해서는 자바에서와 마찬가지로 그 선언을 임포트해야
한다. 스칼라에서는 자바 타입을 임포트하는 다음 예제에서 보여주듯이 다양한 방법을 사용할
수 있다.
import java
.
awt
.
_
import java
.
io
.
File
import java
.
io
.
File
.
_
import java
.
util
.{
Map
,
HashMap
}
첫 줄에서처럼 밑줄 (
_
)을 와일드카드 문자로 사용해서 특정 패키지 안의 모든 타입을 임포트
할 수 있다. 또한 두 번째 줄과 같이 개별 스칼라나 자바 타입을 임포트할 수 있다.
NOTE
_
자바에서는 임포트 시 와일드카드로 별표 문자(
*
)를 사용한다. 스칼라에서는 이 문자를 메서드 이름
에 사용할 수 있다. 그래서 애매함을 없애기 위해 ‘_’를 와일드카드 문자로 사용한다. 예를 들어
Foo
객체에
여러 다른 메서드와 함께
*
메서드가 있다면
import
Foo
.
*
는 어떤 의미여야 할까?
세 번째 줄은
java
.
io
.
File
에서 모든 정적 메서드와 필드를 임포트한다. 이와 동등한 자바 임
포트 문은
import
static
java
.
io
.
File
.*;
일 것이다. 스칼라는
object
타입도 다른 타입과
같이 취급하므로 따로
import
static
문을 제공하지 않는다.
네 번째 줄에 보이는 선택 임포트 문은 아주 유용한 구문이다. 여기서는
java
.
util
.
Map
과
java
.
util
.
HashMap
만 임포트했다.
임포트 문은 아무데나 위치할 수 있다. 따라서 임포트한 타입이나 메서드의 가시 영역을 정확
히 필요한 곳으로만 한정할 수 있다. 임포트하면서 타입의 이름을 바꿀 수 있고, 원치 않는 타
127
2
장
입력은 조금만, 일은 더 많이
입이 보이지 않도록 막을 수 있다.
def stuffWithBigInteger
()
=
{
import java
.
math
.
BigInteger
.{
ONE
=
>
_
,
TEN
,
ZERO
=
>
JAVAZERO
}
//
println
(
"
ONE
:
"+
ONE
)
//
ONE
은
결과적으로
정의되지
않은
상태가
된다
.
println
(
"
TEN
:
"+
TEN
)
println
(
"
ZERO
:
"+
JAVAZERO
)
}
이 임포트 문이
stuffWithBigInteger
안에 있으므로, 그 함수의 바깥에서는 임포트한 타입과
함수를 볼 수 없다.
java
.
math
.
BigInteger
.
ONE
상수를 밑줄(
_
)로 이름을 바꾸면 더 이상 보이지 않으므로 사용 불
가능해진다. 몇몇 타입이나 메서드를 제외한 나머지 전부를 임포트할 때 이런 기법을 사용하라.
다음으로
java
.
math
.
BigInteger
.
TEN
상수를 이름을 바꾸지 않고 임포트한다. 따라서 그냥
TEN
이라고 하면 이 상수를 가리킨다.
마지막으로
java
.
math
.
BigInteger
.
ZERO
상수를 가져오면서
JAVAZERO
라고 ‘별명’을 부여했다.
어떤 대상을 가져오면서 더 쓰기 편한 이름을 부여하고 싶거나, 현재 영역 안에 이름이 겹치는
다른 대상이 있는 경우 별명을 부여하는 것이 유용하다. 자바 타입과 이름이 같은 스칼라 타입
사이의 충돌을 막기 위해 별명을 꽤 자주 사용한다. 예를 들어
java
.
util
.
List
(
http
://
bit
.
ly
/
1sRezAw
)나
java
.
util
.
Map
(
http
://
bit
.
ly
/
13p7wdL
)에는 같은 이름의 스칼라 라이브러리
타입이 존재한다.
2.12.1
임포트는 상대적이다
자바 임포트와 스칼라 임포트의 차이점 중 하나는, 스칼라 임포트가 상대적이라는 것이다. 다
음 임포트 문의 주석을 살펴보자.
128
1
부
스칼라와의 만남
//
src
/
main
/
scala
/
progscala2
/
typelessdomore
/
relative
-
imports
.
scala
import scala
.
collection
.
mutable
.
_
import collection
.
immutable
.
_
//
‘
scala
’
는
항상
임포트된
상태다
.
import
_
root
_
.
scala
.
collection
.
parallel
.
_
//
실제
최상위
패키지로부터의
전체
경로다
.
상대적 임포트가 문제를 일으키는 경우는 거의 없을 것이다. 하지만 때로 예기치 못한 일이 벌어
지곤 한다. 어떤 패키지를 찾을 수 없다는 도무지 원인을 알 수 없는 컴파일러 오류가 발생한다
면, 상대적 임포트와 절대적 임포트를 제대로 사용했는지 다시 한 번 살펴보라. 드물지만
_
root
_
접두사를 붙여야 하는 경우도 있다. 하지만 보통은
com
,
org
,
scala
등의 최상위 패키지로 충
분할 것이다. 또한 문제가 발생한 라이브러리가
CLASSPATH
에 들어 있는지도 확인해야 한다.
2.12.2
패키지 객체
라이브러리 개발자는 설계 시
API
에 대한 공개적 진입점을 어디에 노출해서 사용자가 임포트
하고 사용하도록 만들지 결정해야 한다. 자바 라이브러리의 경우 타입 전부 또는 상당수를 패
키지 안에 정의하는 것이 일반적이다. 예를 들어
import
java
.
io
.*;
라는 문장은
io
패키지의
모든 타입을 임포트한다. 자바
5
부터는 ‘정적 임포트’가 추가되어 클래스의 정적 멤버를 개별적
으로 임포트할 수 있게 되었다. 편리하기는 하지만 여전히 문법은 약간 불편하다.
json
이라는
최상위 패키지와
JSON
이라는 클래스 안에 있는 정적
API
접근 메서드를 통해 사용할 수 있는
가상의
JSON
구문분석 라이브러리를 생각해보자.
static import com.example.json.JSON.*;
스칼라에서는 적어도
static
이라는 키워드를 없앨 수 있다. 하지만 이렇게 쓰는 것은 그리 좋
은 방법이 아니다. 이 임포트 문 하나로
API
사용자가 필요한 모든 타입과 메서드, 값을 노출시
키기 때문이다.
import com.example.json._
Get 프로그래밍 스칼라: 실용적인 스칼라 활용법을 익히는 가장 확실한 실전 바이블 (2.11.x 버전 기반) now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.