2016-07-04 6 views
2

Я читал о языке vala и что он компилируется в код Ansi C. Однако я также видел, что он поддерживает дженерики, такие как Java или Rust. Теперь мой вопрос заключается в том, как это скомпилировано для кода C? Если у меня есть класс или функция gerneric, какой код C генерируется для имитации общего поведения?Vala generics to C code

+0

Допустим, вы пишете общий 'список ', а затем используйте 'list ' и 'list '. Компилятор Vala будет писать C-structs 'list_int' и' list_double', которые имеют соответствующее поведение. Другими словами, работа по созданию конкретного родоразрешения выполняется Валой. – nwp

+1

Разве это не будет таким же, как C++-шаблоны? Но шаблоны не имеют точно такого же поведения, как, как мне кажется, дженериков. – Exagon

+0

C++ шаблоны ведут себя аналогично C# generics (как описано [здесь] (http://stackoverflow.com/a/31929/69809)). Точно так же вали-генерики создадут фактические структуры для каждого генерируемого параметра. – Groo

ответ

5

Вариа дженерики основаны на gpointer и GType.

Вы можете специализироваться только на Generic-классе с параметром типа на основе указателя.

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 файл. Если вы внимательно прочитаете, вы увидите, что для MyClass существует только одна структура (плюс некоторые дополнительные вспомогательные структуры, которые необходимы для классов, основанных на GObject), который имеет член gpointer val, он также имеет 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# generics, чем к классическим шаблонам C++.

Я написал «частично во время компиляции», потому что компилятор Vala достаточно умен, чтобы опустить проверку типа в коде C, когда он знает, что назначение всегда будет правильным.

Также Вала сгенерированный код C предназначен, чтобы быть легко требует минимум ресурсов для других языков программирования, которые имеют GLib привязок (например, C, Python, C++, GJS и т.д.)