[Scala] 가변성 어노테이션

smlee·2023년 9월 4일
0

Scala

목록 보기
31/37
post-thumbnail

스칼라는 제네릭 클래스의 타입 파라미터에 대한 가변성 어노테이션을 지원한다. 스칼라에서는 추상화된 클래스를 정의할 때 가변성 어노테이션을 추가할 수 있다.

다음과 같은 예시 코드를 보자.

class Stack[+T] {
  def push[S >: T](elem: S): Stack[S] = new Stack[S] {
    override def top: S = elem
    override def pop: Stack[S] = Stack.this
    override def toString: String =
      elem.toString + " " + Stack.this.toString
  }
  def top: T = sys.error("no element on stack")
  def pop: Stack[T] = sys.error("no element on stack")
  override def toString: String = ""
}

object VariancesTest extends App {
  var s: Stack[Any] = new Stack().push("hello")
  s = s.push(new Object())
  s = s.push(7)
  println(s)
}

위의 코드는 제네릭을 사용한 코드와 매우 유사하다. 다만 달라진 점이 있다면, 클래스 뒤의 제네릭 표시 앞에 +가 붙은 것이다. 이 키워드의 의미는 무엇일까?

기존의 제네릭 클래스에서는 Stack[T]와 같은 형태로 제네릭을 선언했다면, T 내부에 한 번 설정한 값은 불변자여야 했다. 즉, T 타입의 값만 들어와야 했다. 이는 컴파일 시 오류를 검출해준다는 장점이 있지만, 추상화된 클래스의 재사용을 제한할 수 있기도 했다. 하지만, 가변성 어노테이션인 +T를 사용한다면 이를

어노테이션 +T는 타입 순가변 위치에서만 사용할 수 있는 타입 T를 선언한다. 반면, -T는 역가변 위치에서만 사용할 수 있는 어노테이션이다.

String형인 "hello"와 객체인 new Object(), Int형인 7 모두 타입은 다르지만 스택 안에 잘 들어간 것이 확인된다. 이렇게 항목의 타입이 일반화된 스택을 사용하기 위해서는 가변성 어노테이션을 사용하는 것이 좋다.

Reference

0개의 댓글