타입 추론

타입 추론이란 타입 정보가 타이핑 시에 정해질 뿐만 아니라 프로그램이 돌아가는 중에도 체크됨을 뜻합니다. 따라서 언제나 즉시 타입이 결정될 필요는 없습니다. 예를 들면 지역변수는 타입 어노테이션 없이 선언될 수 있고( 이 때 타입은 Unknown입니다. ), 처음 사용될 때에 그 값에 상응하는 타입을 갖게 됩니다.

타입 출력

프로그램의 아무 곳에서나 type 명령을 사용하여 표현식이 반환하는 타입을 알 수 있습니다. 컴파일 시점에 type 명령은 제거되고 표현식만이 남습니다 :

    var x : Int = type(0);

위 코드는 컴파일 시점에 Int를 출력하고 결과물은 type 명령이 없는 코드와 동일합니다.

이 방법을 이용하면 클래스 파일을 찾아보거나 문서들을 읽는 방법보다 빠르게 타입 정보를 얻을 수 있습니다.

지역변수 추론

타입 추론은 모든 곳에 타입이 명시되지 않아도 엄격한 타입 검사가 이루어질 수 있게 해줍니다. 특히 지역변수는 처음 읽거나 쓰기를 하는 순간에 자동으로 유추됩니다 :

    var loc;
    type(loc); // Unknown<0>을 출력합니다.
    loc = "hello";
    type(loc); // String을 출력합니다.

함수 타입 추론

클래스 메서드나 지역 함수의 매개변수의 타입 선언은 선택입니다. 함수가 처음 호출될 시에 들어온 값에 따라 지역변수처럼 매개변수의 타입이 결정됩니다. 이 특징은 프로그램의 실행 순서에 따라 결과가 달라지는 까다로운 코드를 만들어낼 여지가 있습니다. 아래 코드를 보면 그러한 문제가 나타나있습니다 :

    function f( posx ) {
        // ....
    }
    // ...

    f(134);
    f(12.2); // Error : Float should be Int

첫 호출에 f 함수의 posx의 타입이 Int로 결정됩니다. 두번째 호출에는 컴파일 에러가 일어나는데 왜냐면 f에는 이제 Int 값이 나오거라 예상했지만 Float 값이 들어왔기 때문이죠. 하지만 호출 순서를 바꿔서 Float 값이 먼저 적용된다면 두번째 호출인 Int 값을 인자로 넣은 코드는 Float의 하위 타입이기 때문에 문제가 생기지 않습니다 :

    function f( posx ) {
        // ....
    }
    // ...
    
    f(12.2); // 매개변수 타입이 Float로 결정됨
    f(134); // 성공

위 예제에서 두번의 호출은 코드가 간단해서 쉽게 알아볼 수 있었지만 대부분의 경우에 생기는 컴파일 문제의 경우는 코드가 매우 복잡해서 이 부분을 해결하기가 매우 까다로워질 수 있습니다. 이 때 타입 명시를 해준다면 재컴파일 시에 문제가 생긴 부분을 쉽게 찾아낼 수 있습니다.

첫번째 예에서 타입 명시를 해보겠습니다 :

    function f( posx : Int ) {
        // ....
    }
    // ...

    f(134);
    f(12.2); // 이 부분에서 컴파일이 실패됩니다.

추론과 타입 인자

function f<T>(p: Class<T>): T
{

}

function g(p: Float)
{

}

var a: Dynamic = {};

var b = f(a);

type(b); // 이 때 'b'의 타입을 찾아낼 수가 없습니다. 'Unknown<0>'이 출력됩니다.

g(b);

type(b); // 이 때 'b'의 타입은 'Float'가 됩니다.

위의 코드는 타입 없이 선언된 변수가 함수 호출로 초기화되는 상황을 설명하고 있습니다. 인자화된 타입( 'type parametrized' )을 받는 함수인 fClass<T>를 받고( T는 추상적인 값입니다."타입 인자"에서 다루겠습니다. ) 반환할 값의 타입을 결정합니다. 근데 'T'에 Dynamic 타입 객체가 인자로 들어가는건 말이 안되니까 타입 매개변수 'T'는 알 수 없게 됩니다. 따라서 첫 타입 검사 명령으로는 b의 타입을 알 수가 없게 되고 타입 추론은 Float 매개변수를 받는 g 함수가 호출되서 컴파일러가 b의 타입이 Float라는 것을 알 때까지 지연됩니다. 이러한 까닭에 전자는 "Unknown<0>"을 출력하고 후자는 "Float"를 출력합니다. 타입 추론이 처리되면 그 뒤엔 자연적으로 타입이 변하지 않게 됩니다.

사용자의 선택

타입 추론을 이용하는 것은 여러분의 몫입니다. 변수와 함수의 타입지정을 하지 않고 컴파일러가 여러분 대신 타입을 추론하게 미룰 수도 있고 다른 특별한 처리를 위해 미리 모든 타입을 정의할 수도 있습니다. 가장 좋은 방법은 아마도 그냥 적당히 사용하는 것일 겁니다. 타입을 미리 적어놓음으로써 코드 문서화를 개선하거나 코드의 빠른 작성을 위해 타입 지정을 생략할 수도 있습니다.

Dynamic을 이용( 후에 자세히 다루겠습니다. )하지 않는 모든 경우에 여러분의 프로그램은 엄격한 타입 검사가 적용되고 타입 불일치가 일어나는 부분은 컴파일 시에 즉시 발견됩니다.

«« 문법 - 객체 지향 프로그래밍 »»

version #14095, modified 2012-05-21 07:11:40 by disjukr