[Scala] Generic

smlee·2023년 9월 4일
0

Scala

목록 보기
30/37
post-thumbnail

Scala는 Java 5(즉, JDK 1.5)와 같이 파라미터화된 클래스의 빌트인 자원을 제공한다. 즉, 클래스 내부에서 사용할 데이터 타입을 외부에서 지정할 수 있도록 하는 제네릭 클래스를 사용하면 유용하게 개발이 가능하다. 특히, 컬렉션 클래스의 개발에 유용하다.

제네릭을 사용하면 외부에서 자료형을 지정해줄 뿐만 아니라, 지정된 자료형이 아닌 잘못된 타입이 들어왔을 시 컴파일러가 이를 탐지할 수 있어 안정적이다.

예를 들어 큐(Queue)를 직접 만든다고 생각해보자. 이때 큐의 내부 자료형은 모든 타입이 될 수 있다. 즉, 문자열 큐가 될 수도 있고, Int형 큐가 될 수도 있는 것이다. 이런 경우 어떤 식으로 코드를 작성할까?

class Queue[T] {
  var elems: List[T] = Nil
  def push(x: T): Unit =
    elems = elems :+ x
  def front: T = elems.head
  def pop(): Unit = { elems = elems drop 1 }
}

위와 같이 임의의 타입을 지정하는 T라는 항목의 타입으로 변수형을 지정하였다. 즉, 해당 큐를 사용할 때 필요한 타입을 넣을 수 있도록 한 것이다.

임의의 타입

제네릭에서 임의의 타입을 지정할 때 위와 같은 키워드들로 설정한다.
물론, < E > 대신 < Ele >와 같은 형태로 사용해도 되지만 위의 표에 나와있는 타입들이 통상적으로 사용하는 타입이므로 위와 같이 원하는 description에 맞는 한 글자 키워드를 사용하는 것이 좋다.

위의 큐가 실제로 잘 동작하는지 확인해보자.

Queue 클래스를 보면 임의의 타입인 T를 넣어놓았다. 그리고 현재 만들고 싶은 큐는 Int형이므로 new 키워드로 새로운 큐를 만들 때 중괄호 안에 원하는 타입을 넣어주면 된다.

그 후, 모든 작업들이 제대로 동작하는 것이 보인다. 이때 주의해야할 점은 타입 파라미터는 올바른 항목(타입 T, 예제에서는 Int)만을 사용하도록 강제한다는 점이다.

위의 예시에서는 queue를 Int 타입으로 선언하여 내부에 Int의 값만 들어오도록 강제하는데, 만약 다른 큐에서 다른 데이터 타입(Double이나 Boolean 혹은 객체)이 들어오도록 선언하였다면 그 역시 제대로 동작할 것이다.

위의 코드는 String형으로 만든 다른 큐이다. 위의 코드 역시 내부 자료형은 달라졌지만 의도한 바를 잘 수행하는 것을 알 수 있다. 이처럼 클래스 내부의 임의의 자료형이 들어오는 것을 허용하는 것이 제네릭이다.

또한, 제네릭 클래스의 서브 타입은 "불가변"이다. 이는 상당히 큰 제약이므로 스칼라는 제네릭 타입의 서브타입을 지정하는 행위를 제어하기 위해 타입 파라미터 어노테이션 방법을 제공한다.

Reference

0개의 댓글