2016-07-04 7 views
2

나는 언어 vala에 대해 읽고 Ansi C 코드로 컴파일합니다. 그러나 나는 또한 Java 나 Rust와 같은 generics를 지원한다는 것을 알았다. 이제 내 질문에 어떻게 이것이 C 코드로 컴파일됩니까? gerneric 클래스 또는 함수가있는 경우 일반 동작을 시뮬레이트하기 위해 어떤 종류의 C 코드가 생성됩니까?Vala 제네릭에서 C 코드

+0

는 말 (C, 파이썬, C++, GJS 등 같은) 그런 다음 일반적인'목록 쓰기'와 다른 프로그래밍 언어에 대한 소비하는 의미 생성 'list '과'list '를 사용하십시오. Vala 컴파일러는 적절한 동작을하는 C 구조체'list_int'와'list_double'을 작성할 것입니다. 즉, 특정 제네릭을 인스턴스화하는 작업은 Vala가 수행합니다. – nwp

+1

C++ 템플릿과 동일하지 않습니까? 그러나 템플릿은 제네릭만큼이나 똑같은 동작을하지는 않습니다. – Exagon

+0

C++ 템플릿은 C# 제네릭과 비슷하게 동작합니다 ([여기] (http://stackoverflow.com/a/31929/69809) 설명 참조). 그것은 vala 제네릭이 전달하는 각 일반 매개 변수에 대한 실제 구조체를 만드는 것과 같은 방식입니다. – Groo

답변

5

발타 제네릭은 gpointerGType을 기반으로합니다.

포인터 기반 유형 매개 변수를 사용하여 일반 클래스 만 특수화 할 수 있습니다.

class MyClass<T> { 

public T val; 

} 

public static int main (string[] args) { 
    // This wouldn't compile! 
    // var il = new Gee.ArrayList<int>(); 

    var il = new Gee.ArrayList<int?>(); 
    var dl = new Gee.ArrayList<double?>(); 
    il.add (5); 
    dl.add (3.0); 

    var im = new MyClass<int?>(); 
    im.val = 5; 

    var dm = new MyClass<double?>(); 
    dm.val = 3.0; 

    var lm = new MyClass< Gee.List<int?> >(); 
    lm.val = il; 

    return 0; 
} 

당신은 -C 매개 변수를 사용하여 생성 된 코드를 직접 확인할 수 있습니다

valac -C Main.vala --pkg gee-0.8 

이는 main.c 파일을 생성합니다. 신중하게 읽으면 멤버가 gpointer val 인 MyClass (GObject 기반 클래스에 필요한 몇 가지 추가 도우미 구조체)뿐 아니라 GType t_typet_dup_funct_destroy_func이 하나만 있음을 알 수 있습니다.

struct _MyClass { 
     // ... 
     gpointer val; 
}; 

struct _MyClassPrivate { 
     GType t_type; 
     GBoxedCopyFunc t_dup_func; 
     GDestroyNotify t_destroy_func; 
}; 

GLib type checking에 올바른 유형이 전달되도록합니다. 이렇게하면 Vala 제네릭 형식을 안전하게 사용할 수 있습니다 (부분적으로 컴파일 할 때와 부분적으로 런타임에).

이것은 컴파일 타임에 확장되는 C++ 템플릿과는 대조적입니다. 따라서 고전적인 C++ 템플릿보다 C# 제네릭에 가깝습니다.

Vala 컴파일러는 할당이 항상 정확하다는 것을 알 때 C 코드에서 유형 검사를 생략 할만큼 똑똑하기 때문에 "부분 컴파일시"라고 썼습니다.

또한 발라는 C 코드를 쉽게 입심 바인딩이