2.6 Dynamic
2.6 Dynamic
Haxe는 정적 타입 시스템을 가지지만, Dynamic 타입을 사용하면 본질적으로 그것을 비활성화할 수 있어요. 동적 값(dynamic value) 은 아무 것에나 할당될 수 있고, 아무 것이나 그 값에 할당될 수 있습니다. 여기에는 여러 단점이 있어요:
- 컴파일러는 특정 타입이 기대되는 위치(할당, 함수 호출 등)에서 더 이상 타입 검사를 할 수 없습니다.
- 특히 정적 대상으로 컴파일할 때, 특정 최적화를 더 이상 사용할 수 없어요.
- 필드 접근의 오타 같은 일반적인 오류를 컴파일 타임에 잡지 못해 런타임 오류를 일으킬 가능성이 높아집니다.
- Dead Code Elimination은
Dynamic을 통해 사용되는 필드를 감지하지 못합니다.
Dynamic 사용이 런타임에 문제를 일으키는 예를 쉽게 만들 수 있어요. 다음 두 줄을 정적 대상으로 컴파일해 보세요:
var d:Dynamic = 1;
d.foo;
컴파일된 프로그램을 Flash Player에서 실행하려 하면 Property foo not found on Number and there is no default value라는 오류가 발생합니다. Dynamic이 없다면 이것은 컴파일 타임에 감지됐을 거예요.
Dynamic의 사용은 최소화하는 것이 좋아요. 더 나은 대안이 있는 경우가 많기 때문이죠. 하지만 때로는 실용적인 해법이 되기도 합니다. Haxe Reflection API의 일부는 이것을 사용해요. 또한 컴파일 타임에 알 수 없는 커스텀 데이터 구조를 다룰 때 Dynamic을 쓰는 것이 최선일 수 있어요.
Dynamic은 모노모프(monomorph)와 유니파이될 때 특별한 방식으로 동작해요. 모노모프는 결코 Dynamic에 바인딩되지 않으며, 이는 다음과 같은 예제에서 놀라운 결과를 만들 수 있습니다:
class Main {
static function main() {
var jsonData = '[1, 2, 3]';
var json = haxe.Json.parse(jsonData);
$type(json); // Unknown
for (i in 0...json.length) {
// Array access is not allowed on
// {+ length : Int }
trace(json[i]);
}
}
}
Json.parse의 반환 타입이 Dynamic이지만, 로컬 변수 json의 타입은 그것에 바인딩되지 않고 모노모프로 남아요. 그러면 json.length 필드 접근 시 익명 구조체(anonymous structure)로 추론되어, 뒤따르는 json[0] 배열 접근이 실패합니다. 이를 피하려면 var json:Dynamic처럼 변수 json을 명시적으로 Dynamic으로 타입 지정하면 돼요.
참고(Haxe 3 이전의 Dynamic 추론) — Haxe 3 컴파일러는 타입을 결코
Dynamic으로 추론하지 않으므로, 사용자가 이를 명시해야 합니다. 이전 Haxe 버전은 혼합 타입의 배열(예:[1, true, "foo"])을Array<Dynamic>으로 추론했어요. 우리는 이 동작이 너무 많은 타입 문제를 일으킨다는 것을 발견하고 Haxe 3에서 제거했습니다.
참고(표준 라이브러리의 Dynamic) — Dynamic은 Haxe 3 이전의 Haxe 표준 라이브러리에서 꽤 흔했습니다. Haxe 타입 시스템의 지속적인 개선으로, Haxe 3로 이어지는 릴리스들에서 Dynamic의 사용은 줄어들었어요.
출처: Dynamic
본문
Dynamic의 성격과 단점
Dynamic 타입은 어떤 값이든 담을 수 있는 와일드카드 타입이에요. 하지만 이것은 타입 시스템의 보호를 포기하는 것이므로, 컴파일 타임 타입 검사, 정적 대상 최적화, 필드 오타 감지 같은 이점을 잃어요. 런타임 오류의 위험이 커집니다.
언제 쓰는가
Dynamic은 보통 피하는 것이 좋지만, 때로는 실용적인 해법입니다. Reflection API의 일부와 컴파일 타임에 알 수 없는 데이터 구조를 다룰 때 유용할 수 있어요.
모노모프와의 상호작용
Dynamic은 모노모프와 유니파이될 때 특별히 동작해요. 모노모프는 Dynamic에 바인딩되지 않으므로, haxe.Json.parse 같은 함수의 결과를 받은 변수는 Dynamic이 아니라 모노모프(그리고 곧 익명 구조체)로 추론됩니다. Dynamic의 동작이 필요하다면 변수를 명시적으로 Dynamic으로 선언해야 합니다.