2.7.6 추상 필드 전달(Forwarding abstract fields)

2.7.6 추상 필드 전달(Forwarding abstract fields)

Haxe 3.1.0 이후 — 기반 타입을 감쌀 때, 때로는 그 기능의 일부를 "유지"하고 싶을 수 있어요. 전달 함수를 손으로 쓰는 것은 번거롭기 때문에, Haxe는 추상 타입에 @:forward 메타데이터를 추가할 수 있게 해줍니다:

@:forward(push, pop)
abstract MyArray<Array<T>> (Array<T>) {
  public inline function new() {
    this = [];
  }
}

class Main {
  static public function main() {
    var myArray = new MyArray();
    myArray.push(12);
    myArray.pop();
    // MyArray has no field length
    // myArray.length;
  }
}

이 예제의 MyArray 추상은 Array를 감쌉니다. @:forward 메타데이터에는 기반 타입으로 전달할 필드 이름에 대응하는 두 인자가 있어요. main 메서드는 MyArray를 인스턴스화하고 pushpop 메서드에 접근합니다. 주석 처리된 줄은 length 필드는 사용할 수 없음을 보여줘요.

평소처럼 JavaScript 출력을 보면 코드가 어떻게 생성되는지 확인할 수 있습니다:

Main.main = function() {
    var myArray = [];
    myArray.push(12);
    myArray.pop();
};

@:forward는 인자 없이 사용해 모든 필드를 전달할 수 있어요. 물론 Haxe 컴파일러는 여전히 필드가 기반 타입에 실제로 존재하는지 확인합니다.

참고(매크로로 구현됨)@:enum@:forward 기능 모두 원래 빌드 매크로(build macros)로 구현되었어요. 비-매크로 코드에서는 잘 동작했지만, 매크로 안에서 이 기능들을 사용하면 문제가 생겼습니다. 구현은 이후 컴파일러로 옮겨졌어요.

출처: Forwarding abstract fields

본문

@:forward의 사용

@:forward(필드명, ...) 메타데이터는 추상이 기반 타입의 특정 필드를 그대로 노출(전달)하게 해줍니다. 손으로 전달 함수를 쓰는 번거로움을 없애줘요. 이름을 나열하지 않으면 모든 필드가 전달됩니다.

예제 분석

MyArray 추상은 Array를 감싸면서 @:forward(push, pop)으로 pushpop만 전달해요. 그래서 myArray.push(12)myArray.pop()은 가능하지만, length는 전달 목록에 없어 접근할 수 없습니다.

구현 변경

원래 @:enum@:forward는 빌드 매크로로 구현됐지만, 매크로 내부에서 사용 시 문제가 있어 컴파일러 내장 기능으로 옮겨졌어요.

더 알아보기