타입 자동 캐스팅

타입 자동 캐스팅 (Type autocasting)

Crystal은 모호함이 없을 때 특정 타입의 요소를 투명하게 캐스팅해요.

숫자 자동 캐스팅 (Number autocasting)

숫자 타입의 값은 정밀도가 손실되지 않는다면 더 큰 타입으로 자동 캐스팅돼요:

def foo(x : Int32) : Int32
  x
end

def bar(x : Float32) : Float32
  x
end

def bar64(x : Float64) : Float64
  x
end

foo 0xFFFF_u16 # OK, an UInt16 always fit an Int32
foo 0xFFFF_u64 # OK, this particular UInt64 fit in an Int32
bar(foo 1)     # Fails, casting an Int32 to a Float32 might lose precision
bar64(bar 1)   # OK, a Float32 can be autocasted to a Float64

숫자 리터럴은 그 타입과 관계없이 실제 값이 목표 타입에 들어맞을 때 항상 캐스팅돼요.

표현식도 캐스팅이 돼요(위 마지막 예시처럼). 다만 컴파일러에 no_number_autocast 플래그가 전달되면 예외예요(자세한 내용은 Compiler features 참고).

모호함이 있을 때, 예를 들어 선택지가 둘 이상이면 컴파일러가 에러를 던져요:

def foo(x : Int64)
  x
end

def foo(x : Int128)
  x
end

foo 1_i32 # Error: ambiguous call, implicit cast of Int32 matches all of Int64, Int128

자동 캐스팅은 지금은 두 가지 상황에서만 동작해요. 지금까지 본 함수 호출과, 클래스·인스턴스 변수 초기화요. 아래 예시는 인스턴스 변수의 두 상황을 보여줘요. 초기화에서의 캐스팅은 되지만, 대입에서의 캐스팅은 되지 않아요:

class Foo
  @x : Int64 = 10 # OK, 10 fits in an Int64

  def set_x(y : Int32)
    @x = y
  end
end

Foo.new.set_x 1 # Error: "at line 5: instance variable '@x' of Foo must be Int64, not Int32"

심볼 자동 캐스팅 (Symbol autocasting)

심볼은 enum 멤버로 자동 캐스팅돼서, 더 간결하게 쓸 수 있어요:

enum TwoValues
  A
  B
end

def foo(v : TwoValues)
  case v
  in TwoValues::A
    p "A"
  in TwoValues::B
    p "B"
  end
end

foo :a # autocasted to TwoValues::A

출처: Crystal 공식 문서

더 알아보기 (Learn more)

  • 관련 내용으로 컴파일 플래그는 Compiler features 문서를 확인해 보세요.