나는 언어 vala에 대해 읽고 Ansi C 코드로 컴파일합니다. 그러나 나는 또한 Java 나 Rust와 같은 generics를 지원한다는 것을 알았다. 이제 내 질문에 어떻게 이것이 C 코드로 컴파일됩니까? gerneric 클래스 또는 함수가있는 경우 일반 동작을 시뮬레이트하기 위해 어떤 종류의 C 코드가 생성됩니까?Vala 제네릭에서 C 코드
2
A
답변
5
발타 제네릭은 gpointer
및 GType
을 기반으로합니다.
포인터 기반 유형 매개 변수를 사용하여 일반 클래스 만 특수화 할 수 있습니다.
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_type
과 t_dup_func
및 t_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 코드를 쉽게 입심 바인딩이
는 말 (C, 파이썬, C++, GJS 등 같은) 그런 다음 일반적인'목록 쓰기'와 다른 프로그래밍 언어에 대한 소비하는 의미 생성 'list '과'list '를 사용하십시오. Vala 컴파일러는 적절한 동작을하는 C 구조체'list_int'와'list_double'을 작성할 것입니다. 즉, 특정 제네릭을 인스턴스화하는 작업은 Vala가 수행합니다. –
nwp
C++ 템플릿과 동일하지 않습니까? 그러나 템플릿은 제네릭만큼이나 똑같은 동작을하지는 않습니다. – Exagon
C++ 템플릿은 C# 제네릭과 비슷하게 동작합니다 ([여기] (http://stackoverflow.com/a/31929/69809) 설명 참조). 그것은 vala 제네릭이 전달하는 각 일반 매개 변수에 대한 실제 구조체를 만드는 것과 같은 방식입니다. – Groo