Язык программирования Vala: делегаты и обобщенные классы
Содержание:
1. Hello world!;
2. Строки, массивы и управляющие конструкции ;
3.Делегаты и обобщенные классы (Вы читаете данный раздел);
4. Контрактное программирование и библиотека обобщенных контейнеров Gee.
В Vala и Genie нет указателей на функции. Если необходимо передать функцию в виде параметра другой функции, то используются делегаты:
Код с делегатами гораздо лучше читается, чем код с указателями на функции в С/С++.
Делегатам можно присваивать как обычные, так и анонимные функции:
Анонимные функции являются замыканиями, т. е. они «помнят» контекст своего создания и могут обращаться к любым переменным из этого контекста:
Здесь функция get_adder() возвращает делегата, который производит сложение своего аргумента с «внешней» по отношению к нему переменной. В отличие от языка D в Vala нет отдельных типов для «истинных замыканий» и «чистых» анонимных функций - все лямбда-функции являются замыканиями.
Полезно знать! Некоторые умельцы умудряются создавать на Vala игры на андроид (http://androvip.ru/igru-na-adroid/). Качество страдает, но оптимизация находится на достаточно хорошем уровне и в некоторые из них даже можно играть!
Vala поддерживает обобщенные классы, т. е. классы, которые могут работать с разными типами данных. Конкретный тип данных указывается при создании экземпляра класса. Обобщенные классы (Generics) не являются полным аналогом шаблонов (Templates) в С++ или D. Единственное назначение обобщенных классов - избежать написания одного и того же кода для нескольких типов данных, которые обрабатываются одинаковым образом. Обобщенные классы не предназначены для шаблонного метапрограммирования, как в С++. Синтаксис обобщенных классов в Vala похож на шаблоны в С++, но более прост. Имя обобщенного типа задается в угловых скобках:
Обобщенные классы Vala имеют еще одно существенное отличие от С++: ограничение типа происходит на этапе выполнения, а не компиляции. Т.е. Adder и Adder - объекты одного и того же класса, а не двух разных, как в С++. Такая система больше напоминает обобщенные классы Java.
1. Hello world!;
2. Строки, массивы и управляющие конструкции ;
3.
4. Контрактное программирование и библиотека обобщенных контейнеров Gee.
Делегаты
В Vala и Genie нет указателей на функции. Если необходимо передать функцию в виде параметра другой функции, то используются делегаты:
delegate void DelegateType(int a);
void f1(int a) {
stdout.printf("%dn", a);
}
void f2(DelegateType d, int a) {
d(a); // Вызов делегата с переданным параметром
}
void main() {
f2(f1, 5); // Функция f1 передается в параметре-делегате
}
void f1(int a) {
stdout.printf("%dn", a);
}
void f2(DelegateType d, int a) {
d(a); // Вызов делегата с переданным параметром
}
void main() {
f2(f1, 5); // Функция f1 передается в параметре-делегате
}
Код с делегатами гораздо лучше читается, чем код с указателями на функции в С/С++.
Делегатам можно присваивать как обычные, так и анонимные функции:
delegate void PrintIntFunc(int a);
PrintIntFunc p = (a) => stdout.printf("%dn", a);
p(20);
PrintIntFunc p = (a) => stdout.printf("%dn", a);
p(20);
Анонимные функции являются замыканиями, т. е. они «помнят» контекст своего создания и могут обращаться к любым переменным из этого контекста:
delegate int IntOperation(int i); IntOperation get_adder(int a) {
return (b) => a + b; // 'a' - внешняя переменная J для лямбда-функции
}
void main() {
stdout.printf("2 + 4 = %dn", get_adder(2)(4));
}
return (b) => a + b; // 'a' - внешняя переменная J для лямбда-функции
}
void main() {
stdout.printf("2 + 4 = %dn", get_adder(2)(4));
}
Здесь функция get_adder() возвращает делегата, который производит сложение своего аргумента с «внешней» по отношению к нему переменной. В отличие от языка D в Vala нет отдельных типов для «истинных замыканий» и «чистых» анонимных функций - все лямбда-функции являются замыканиями.
Полезно знать! Некоторые умельцы умудряются создавать на Vala игры на андроид (http://androvip.ru/igru-na-adroid/). Качество страдает, но оптимизация находится на достаточно хорошем уровне и в некоторые из них даже можно играть!
Обобщенные классы
Vala поддерживает обобщенные классы, т. е. классы, которые могут работать с разными типами данных. Конкретный тип данных указывается при создании экземпляра класса. Обобщенные классы (Generics) не являются полным аналогом шаблонов (Templates) в С++ или D. Единственное назначение обобщенных классов - избежать написания одного и того же кода для нескольких типов данных, которые обрабатываются одинаковым образом. Обобщенные классы не предназначены для шаблонного метапрограммирования, как в С++. Синтаксис обобщенных классов в Vala похож на шаблоны в С++, но более прост. Имя обобщенного типа задается в угловых скобках:
public class Adder : GLib.Object { private G data; public void do(G a, G b) { this.data = a+b;
}
public G get_sum() { return this.data;
}
}
var v = new Adder ();
}
public G get_sum() { return this.data;
}
}
var v = new Adder
Обобщенные классы Vala имеют еще одно существенное отличие от С++: ограничение типа происходит на этапе выполнения, а не компиляции. Т.е. Adder