typeof

typeof (타입 알아내기)

값이 아니라 그 값의 타입을 알고 싶을 때가 있어요. typeof 표현식은 주어진 표현식의 타입을 반환해요. 실제로 값을 계산하지 않기 때문에, 컴파일 타임에 타입만 꺼내 쓸 수 있어요. 제네릭 코드를 만들 때 특히 유용하죠.

출처: Crystal 공식 문서 - typeof

본문

typeof 표현식은 표현식의 타입을 반환해요.

a = 1
b = typeof(a) # => Int32

여러 인자를 받을 수도 있는데, 이 경우 결과는 표현식 타입들의 **유니온(union)**이 돼요.

typeof(1, "a", 'a') # => (Int32 | String | Char)

이것은 제네릭 코드에서 컴파일러의 타입 추론 능력을 활용하기 위해 자주 사용돼요.

hash = {} of Int32 => String
another_hash = typeof(hash).new # :: Hash(Int32, String)

typeof는 표현식을 실제로 평가하지 않으므로, 컴파일 타임에 메서드에도 사용할 수 있어요. 이 예시는 중첩된 제네릭 타입으로부터 재귀적으로 유니온 타입을 만드는 코드예요.

class Array
  def self.elem_type(ary)
    if ary.is_a?(Array)
      elem_type(ary.first)
    else
      ary
    end
  end
end

nest = [1, ["b", [:c, ['d']]]]
flat = Array(typeof(Array.elem_type(nest))).new
typeof(nest) # => Array(Int32 | Array(String | Array(Symbol | Array(Char))))
typeof(flat) # => Array(String | Int32 | Symbol | Char)

typeof는 실행되지 않으므로 실제 값이 무엇이든 상관없이 타입만 추론해서 반환해요. 그래서 이런 식으로 타입 조합을 만들 수 있는 거예요.

이 표현식은 타입 문법에서도 사용할 수 있어요.

더 알아보기

  • 타입을 표현하는 문법 전반은 타입 문법에서 확인할 수 있어요.
  • 제네릭 타입을 만들 때 쓰는 문법은 Generics 문서에서 다뤄요.