Форум русскоязычного сообщества Ubuntu


Автор Тема: Уроки и примеры по ЯП-у Vala  (Прочитано 35013 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
« Последнее редактирование: 11 Декабря 2016, 00:15:02 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Установка компилятора и первая программа
« Ответ #1 : 02 Февраля 2014, 20:02:20 »
В кратце о компиляторе: код на Vala сначала транслируется(переводится) на C, а потом код на C компилируется(превращается в исполнительный файл). В отличии от C подобных языков код Vala значительно проще, удобнее для восприятия. Например, нам не нужно вручную управлять памятью, следовательно для программирования на Vala вам потребуется гораздо меньше опыта. Кроме того в отличии от Java и Python программа выполняется гораздо быстрее посколюку она она не транслируется,  компилируется. А поскольку Vala основан на C он имеет такую же мощь как C или C++(если вы помните сначала код с C++ транслировался на C, потом появился отдельный компилятор). Поддерживается ООП, однако намного проще чем C++.
Переходим к практике: ставим компилятор-транслятор.

В любимом редакторе набираем код:
Код: (vala) [Выделить]
int main() // С этой строки начинается выполнение программы
{   // Код в функции между фигурными скобками
    /* Код между 2 наклоненными линями или слешем(наклоненая линия) и
    звездочкой это комментарий. В первом случае комментарий до конца
    строки,во втором до звездочки и слеша. На работу не влияют, нужны для
    понимания кода*/
    // выводим на экран строку
    stdout.printf("Привет, как тебя зовут? ");
    /* Ждем ввода пользователя, сохраняем его в
    переменной imya типа string
    Переменные начинаются с латинской буквы,
    далее разрешены цифры, подчеркивание*/
    string imya = stdin.read_line();
    // Знакомый вывод. Символ @ позволяет подставлять значения переменных
    //Для этого перед именем переменной ставим символ $
    stdout.printf(@"Привет $imya\n");
    //Завершаем работу процедуры(в данном случае программы)
    // ноль означает отсутствие ошибок
    return 0;
}
И сохраняем в любом файле с расширением .vala. Например v1.vala
Компилируем: valac v1.vala Ошибок нет? Запускаем: ./v1 Сохраняем исполняемый файл с другим именем: valac -o v2 v1.valaТранслируем в код на C(обратите внимание не C++): valac -C v1.vala Создаем объектный файл:valac -c v1.vala Получаем заголовочный файл: valac -H v1.vala Компиляция и запуск - самые нужные команды. Если не знаете зачем нужны остальные команды - значит они вам и не нужны.
А вот пример работы программы:
alsoijw@alsoijw-Aspire-4315 ~/Документы/vala $ ./v2
Привет, как тебя зовут?
alsoijw
Привет alsoijw
И еще один приятный момент - у Vala и его близкого родственника Genie есть интерпретатор, который сначала транслирует код и сохраняет его во временной папке, а потом запускает его. Вот пример его работы
alsoijw@alsoijw-Aspire-4315 ~/Документы $ vala 1.vala
/tmp/1.vala.OCGDBX.c: В функции «main»:
/tmp/1.vala.OCGDBX.c:171:2: предупреждение: «g_type_init» is deprecated (declared at /usr/include/glib-2.0/gobject/gtype.h:669) [-Wdeprecated-declarations]
SuperClass.method_1()
SubClass.method_1()
alsoijw@alsoijw-Aspire-4315 ~/Документы $ ./1
bash: ./1: Нет такого файла или каталога
alsoijw@alsoijw-Aspire-4315 ~/Документы $
« Последнее редактирование: 01 Июня 2014, 23:13:47 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Переменные и математика
« Ответ #2 : 03 Февраля 2014, 20:48:45 »
Пожалуй следующая жизненно важная тема - это переменные. К этой теме мы будем еще не раз обращаться.
После чего мы сможем пользоваться переменной? После обновления. Как это сделать? Синтаксис такой:
Код: (Vala) [Выделить]
ImyaTipa peremennaya; Вы видите точку с запятой? Не забывайте про нее. Предположим нам  нужна переменная Int типа int
Код: (Vala) [Выделить]
int Int; Как видим Vala различает переменные не только по написанию, но и по регистру.
Как что-то сохранить в переменной?
Код: (Vala) [Выделить]
ImyaTipa = Znachenie;Значением может быть любое значение того же типа. Но если типы разные, и преобразовать из одного типа в другой нельзя, тогда будет выброшено исключение, и программа завершит работу. Попозже мы поговорим о других типах. А пока знакомимся с новым типом - целочисленная переменная -
Код: (Vala) [Выделить]
int. В ней могут хранится разные целые числа. Дробная часть отбрасывается. Правда слишком большие числа в него не влезут, но позже мы узнаем как это решить. Второй тип - числа с плавающей точкой
Код: (Vala) [Выделить]
doubleИз одного в другой эти числа преобразуются без проблем, но при присвоении числу типа int дробного значения дробная часть "теряется". Если вам кажется что числа типа int непрактичны, то вы удивитесь узнав что у них "другое назначение", не такое как у double. Например они нужны в счетчиках.
И в заключение: в строке может содержаться число, но умножать или складывать строки как числа нельзя. Вот мы извлекаем из строки число, превращаем число в строку. Если преобразовать нельзя(например в числе буква или это не число, а слово) то тогда переменная приравнивается к нулю.
Код: (Vala) [Выделить]
bool b = bool.parse("false");
int i = int.parse("-52");
double d = double.parse("6.67428E-11");
string s1 = true.to_string();
string s2 = 21.to_string();
Правда я еще ничего не сказал про тип bool, но думаю это тема следующего урока.
А теперь вернемся к математике. Вот делим, умножаем, складываем, вычитаем
Код: (Vala) [Выделить]
double a, b; // Можно объявлять и так, чтоб не писать кучу раз тип
a = 5;
b = 2;
stdout.printf((a/b).to_string() + "\n");
//Вручную переводим в строку, а то компьютер не догадается
//+ "\n"добавляем к строке символ переноса каретки, чтоб было красиво
stdout.printf((a*b).to_string() + "\n");
stdout.printf((a+b).to_string() + "\n");
stdout.printf((a-b).to_string() + "\n");
Можно и сохранить в какой то переменной
Код: (vala) [Выделить]
double c = a + b;Помните тип int не предназначен для математических расчетов, его цель другая. Если делить два числа типа int мы теряем дробную часть. Чтоб этого не произошло надо преобразовать int в double.
Код: (vala) [Выделить]
int a = 5, b = 2;
double c = (double)a/c //c = 2.5
//(тип)переменная нужно для преобразования переменная в тип
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Куда же без логики
« Ответ #3 : 05 Февраля 2014, 17:56:16 »
Как я и обещал, сейчас мы поговорим о логике. Булевая переменная может хранить только два значения.
Код: (vala) [Выделить]
bool BoolVar; // Объявляем булевую переменную. Значение по умолчанию - true
BoolVar = true; BoolVar = false //Соответственно правда и ложь
Теперь мы можем управлять выполнением программы
Код: (vala) [Выделить]
if (условие) { операторы }//эта часть быть обязана
else if (условие) { операторы } // Может использоваться несколько раз, необязательна
// В отличии от предыдущих - выполняется всегда, если ни одно из предыдущих не выполнилось
else { операторы }
Если блок операторов состоит из одой команды - ставить скобки не обязательно.
А теперь поговорим об условиях. Операции сравнения
Код: (vala) [Выделить]
a < b
a > b //Это я думаю вам понятно
a >= b //больше или равно
a <= b //меньше или равно
a != b //не равно
a == b //равно
Однако иногда нам нужно объединять или превращать в противополжное условия
Код: (vala) [Выделить]
!a //не - меняет значение на противоположное
a && b //и - истина только если и тот и другой операнд - истина
a || b //или - истина если хотя бы один операнд - истина
a ^ b //исключающее или - истина если операнды не равны
И на конец оператор выбирающий один вариант из нескольких значений одной переменной
Код: (vala) [Выделить]
switch (a) //выбираем переменную для анализа
{
case 1://выбираем требуемое значение
    операторы
    break;
    // Не забываем про эту строку, без нее не откомпилируется
    // Она говорит о том что этот вариант закончился
    // и далее начнется следующее условие.
case 2:break;
case 3:
    операторы
    break;
default://если ни одно из условий не оказалось истинным
    операторы
    break;
}
Да и напоследок: vala не позволяет перепутать присвоение = и  равенство ==. Удобнее чем C++.
« Последнее редактирование: 09 Февраля 2014, 19:01:54 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Знакомство с ООП
« Ответ #4 : 06 Февраля 2014, 19:45:41 »
Да пожалуй без ООП далеко не уедешь. В самом начале мы создадим очень простой класс
Код: (vala) [Выделить]
public class TestClass1 //Так объявляется новый класс
{
    public void test_metod()
    {
        print ("hello, world\n");
    }
}
Сам по себе этот код работать не будет, но если создать экземпляр этого класса - то мы сможем использовать код этого класса. В функции main создаем переменную типа TestClass1. Думаю вы уже поняли как это сделать
Код: (vala) [Выделить]
int main()
{
    TestClass1 Var; // Объявляем переменную только что созданного типа
    Var = new TestClass1(); // Создаем переменную только что созданного типа
    Var.test_metod(); /* Используем функцию этого объекта или попросту метод
    после имени функции идут скобки*/
    return 0;
}
Вы сохранили этот код в одном файле? Да сейчас мы можем это делать, но в больших программах хранить весь исходный код в одном файле неудобно. Если вы изучали C или C++ то уже думаете: будем создавать заголовочный файл. Но это делать не нужно. Более того, если код в таком виде сохранить в разных файлах, то для их компиляции не потребуется импортирования, подключения...(это для тех кто знает что это такое)
Как откомпилировать? Не вносите ни каких дополнительных изменений, просто скопируйте и сохраните в разных файлах. А теперь в терминале вводим:
Код: (bash) [Выделить]
valac v1.vala v2.vala -o vПредполагается что в папке есть файлы v1.vala v2.vala. Обратите внимание, ключ -o обязателен, далее имя бинарного файла. Запускаемalsoijw@alsoijw-Aspire-4315 ~/Документы/vala/новая папка $ ./v
hello, world
alsoijw@alsoijw-Aspire-4315 ~/Документы/vala/новая папка $
Гениально работает! Напоследок о методах, и переменных класса. В классе могут быть свои переменные. Модифицируйте файл с кодом класса, и посмотрите как это работает. В заключение скажу что переменных и методов может быть много. Подробнее поговорим о них позже.
Код: (vala) [Выделить]
public class veryimpotant1
{
    public int t;

    public void temp()
    {
        t = 5;
        print (@"hello, world$t\n");
    }
}
Теперь создав экземпляр класс мы можем обращаться к переменной t.
Код: (vala) [Выделить]
int main()
{
    TestClass1 Var;
    Var = new TestClass1();
    print (Var.t.to_string()); // После переменных скобки не нужны
    return 0;
}
« Последнее редактирование: 25 Февраля 2014, 20:01:52 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Наследование и интерпретатор для Vala
« Ответ #5 : 25 Февраля 2014, 00:12:15 »
Сейчас вкратце рассмотрим наследование.
Код: (vala) [Выделить]
public class SuperClass
{
    public void Method()
    {
        stdout.printf ("SuperClass\n");
    }
}

public class SubClass : SuperClass
{
   
}

void main()
{
    var S = new SubClass();
    // Если при создании переменой транслятор может
    // Определить тип - не обязательно его указывать полностью
    // Это короче чем и красивее SubClass S = new SubClass();
    S.Method();
}

Мы видим - производный класс может работать с элементами суперкласса.
А вот пример переопределения метода
Код: (vala) [Выделить]
class SuperClass : GLib.Object
{
    public void Method()
    {
        stdout.printf("SuperClass.method_1()\n");
    }
}

class SubClass : SuperClass
{
    public void Method()
    {
        stdout.printf("SubClass.method_1()\n");
    }
}

void main()
{
    var S = new SubClass();
    var S1 = new SuperClass();
    S1.Method();
    S.Method();
}
Класс от которого унаследован данный класс принято называть суперклассом, унаследовавший - субклассом.
« Последнее редактирование: 01 Июня 2014, 23:08:38 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Передача аргументов по значению и по ссылке
« Ответ #6 : 28 Февраля 2014, 20:06:25 »
В этом уроке мы немного поговорим об аргументах методов(функций). Как известно, каждой функции при ее вызове можно передать какую-то информацию с помощью аргументов. Однако функция может их не только прочитать, но и изменить их. Чтобы понять это запустите пример
Код: (vala) [Выделить]
void main()
{
    int a = 0;
    stdout.printf(@"$a\n");
    ByVal(a);
    stdout.printf(@"$a\n");
    //Если переменная предается по ссылке
    //надо не забыть написать ref
    ByRef(ref a);
    stdout.printf(@"$a\n");
}

void ByRef(ref int a)
//Переменная передается по ссылке
{
    a = 7;
}

void ByVal(int a)
//Переменная передается по значению
{
    a = 7;
}
А вот результат ее работы0
0
7
Как мы видим при передаче переменной по ссылке мы можем менять ее значение в вызвавшем ее коде. Понятное дело что и в той и в другой функции после операторов присваивания значение переменной изменилось. но при передаче переменной по значению создается копия переменной, а к оригиналу функция доступа не имеет.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Вкратце о массивах
« Ответ #7 : 25 Марта 2014, 17:36:13 »
Итак в этом уроке рассмотрим создание массивов.
Простым языком - это несколько элементов под одним именем, доступ к любому элементу можно получить по номенру.
Их можно создавать несколькими способами.
Код: (vala) [Выделить]
int[] a = new int[10];//Во вторых скобочках указываем число элементов
int[] b = { 2, 4, 6, 8 };
a[3]=6;//Обращаемся к 3 элементу
stdout.printf(a[3].to_string());
stdout.printf(a.length);//Узнаем количество элементов
foreach (int a_v in a) { stdout.printf("%d\n", a_v); }//Самый простой метод перебрать все элементы
a.resize(12);//Изменяем размер
И важное предупреждение: если вы случайно обратитесь к не существующему элементу - вас не кто не остановит. Хорошо если только прочтет, а если измените - может вызвать проблемы
« Последнее редактирование: 02 Июня 2014, 10:16:03 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
циклы for и ключи
« Ответ #8 : 22 Апреля 2014, 22:10:18 »
В этом уроке мы рассмотрим работу цикла, и получение аргументов при запуске программы.
Код: (vala) [Выделить]
void main()
{
for (int a = 0; a < 10; a+=2)
//сначала инициализируем счетчик, но он может быть объявлен и ранее см 2 пример
//второе - условие завершения работы цикла
//насколько увеличивать значение каждый раз
{
stdout.printf("%d\n", a);
}
}

Код: (vala) [Выделить]
void main(string[] args)
{
int a;
for (a = 0; a < 10; a++)
{
stdout.printf("%d\n", a);
}
}
Аргументы передающиеся программе при запуске - массив строк.
Код: (vala) [Выделить]
void main(string[] args1)
{
foreach (string s in args1)
{
stdout.printf(@"$s \n");
}
}
А вот пример ее работы:./1 -tt -g
./1
-tt
-g
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Конструкторы в Vala
« Ответ #9 : 01 Июня 2014, 22:54:56 »
Поговорим о конструкторах. Конструктор - процедура функция создающая новый экземпляр класса класса.
Код: (vala) [Выделить]
public class first
{
public first()
{
stdout.printf("Экземпляр класса создан\n");
}
}

public void main()
{
var f = new first();
}
Конструктор с параметрами
Код: (vala) [Выделить]
public class first
{
public first(int i)
{
stdout.printf(@"$i \n");
}
}

public void main()
{
var f = new first(0);
}
А теперь пример вызова конструктора суперкласса в субклассе
Код: (vala) [Выделить]
public class first
{
public first(int i)
{
stdout.printf("%d \n", i);
}
}

public class second : first
{
public second()
{
base(0);
}
}
public void main()
{
var f = new second();
}
Если забыли что такое суперкласс и субкласс смотрите тут
« Последнее редактирование: 02 Июня 2014, 10:17:53 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Сравнение и приравнивание классов и структур
« Ответ #10 : 13 Января 2015, 17:50:15 »
В Vala существуют классы и структуры. Между ними существует разница. Классы сравниваются, приравниваются по ссылке.
Пример
Код: (vala) [Выделить]
void main()
{
Test t1;
Test t2;
t1 = new Test()
t2 = t1
t1.val = 5;
stdout.printf("%d\n", t2.val);
}

class Test
{
public int val;
}
Выполняем и получаем 5. Для примера нарисую схему.
Сначала, после выполнения 3 строки создаётся объект t1, t2 ведёт в никуда.t1 -> 0x...
t2 -> null
После выполнения 4 строчки t2 ссылается на то же самый объектt1 -> 0x...
       ^
       |
t2 ----+
Классы сравниваются по ссылке.
Код: (vala) [Выделить]
void main()
{
var t1 = new Test();
var t2 = new Test();
if(t1 == t2)
{
stdout.printf("==\n");
}
stdout.printf("%d %d\n", t1.val, t2.val);
}

class Test
{
public int val;
}
Как вы уже догадались программа выведет 0 0 так как t1 и t2 указывают на разные участки памяти.
Теперь рассмотрим структуры.
Код: (vala) [Выделить]
void main()
{
var t1 = Test();
var t2 = t1;
t1.val = 5;
stdout.printf("%d\n", t2.val);
}

struct Test
{
public int val;
}
Вывод: 0.
Код: (vala) [Выделить]
void main()
{
var t1 = Test();
var t2 = Test();
if(t1 == t2)
{
stdout.printf("==\n");
}
stdout.printf("%d %d\n", t1.val, t2.val);
}

struct Test
{
public int val;
}
Запускаем==
0 0
Структуры сравниваются по значению.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Примеры оконного приложения и анимации
« Ответ #11 : 24 Марта 2015, 00:53:28 »
Теперь немного примеров. Оконное приложение.
Код: (vala) [Выделить]
using Gtk;

int main (string[] args) {
Gtk.init (ref args);
var window = new Window ();
/* Устанавливаем заголовок окна*/
window.title = "First GTK+ Program";
window.border_width = 10;
/*Окно будет показано в центер экрана*/
window.window_position = WindowPosition.CENTER;
/*Указываем размер окна*/
window.set_default_size (350, 70);
/*Указываем какая функция будет вызвана при закрытии окна
Подробнее о событиях позже*/
window.destroy.connect (Gtk.main_quit);
/*Создаём кнопку и говорим что произойдёт при нажатии*/
var button = new Button.with_label ("Click me!");
button.clicked.connect (() => {
/*Надпись на кнопке изменится на "Thank you"*/
button.label = "Thank you";
});
/*Добавляем кнопку к окну*/
window.add (button);
/*Показываем окно*/
window.show_all ();
Gtk.main ();
return 0;
}
Собираемvalac --pkg gtk+-3.0 имя\ файла.valaА вот самый простой пример двухмерной векторной анимации
Код: (vala) [Выделить]
using Gtk;
using Cairo;

public class Animation : Gtk.Window
{
private int x;
private int s_x;
private const int speed = 3;

public Animation()
{
this.title = "Animation";
this.destroy.connect(Gtk.main_quit);
set_default_size(400, 400);
var drawing_area = new DrawingArea();
drawing_area.draw.connect(on_draw);
add(drawing_area);
s_x = speed;
}

private bool on_draw(Widget da, Context ctx)
{
/*Устанавливаем цвет. Обратите внимание - значение яркости канала от 0 до 1*/
ctx.set_source_rgb(0x9A / 255.0, 0xCD / 255.0, 0x32 / 255.0);
/*Рисуем квадрат*/
draw_sq(ctx);
return true;
}

private void draw_sq(Context ctx)
{
ctx.save();
/*Простейший код движения, с отскоком от краёв*/
if(x > 350)
{
s_x = -speed;
}
else if(x < 0)
{
s_x = speed;
}
x += s_x;
/*Рисуем квадрат*/
ctx.new_path();
ctx.move_to(x, 200);
ctx.rel_line_to(50, 0);
ctx.rel_line_to(0, 50);
ctx.rel_line_to(-50, 0);
ctx.close_path();
ctx.fill();
ctx.restore();
}

static int main (string[] args)
{
Gtk.init(ref args);
var cairo_sample = new Animation();
cairo_sample.show_all();
/*Прорисовка осуществляется 60 раз в секунду
Если закоментировать следующую строчку, то прорисовка будет не регулярной,
например при разворачивании окна*/
Timeout.add(17,()=>{cairo_sample.queue_draw();return true;});
Gtk.main();
return 0;
}
}
Если что не понятно - задавайте вопросы.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Коварные стороны математики
« Ответ #12 : 06 Июня 2015, 10:36:19 »
Сейчас мы рассмотрим тему коварства математики в vala
(Нажмите, чтобы показать/скрыть)
Например у нас есть такой код
Код: (vala) [Выделить]
void main()
{
var a = 0.1;
var b = 0.2;
if(a + b == 0.3)
{
stdout.printf("Равно\n");
}
else
{
stdout.printf("Не равно\n");
}
}
Что будет после того как мы запустим этот код? Забудьте то чему вас учили в школе :). Выведется
Цитировать
Не равно
Не верите? Проверьте у себя. :). Почему так происходит? При переводе некотрых десятичных дробных чисел получается безконечная двоичная дробь, которая округляется. Но для компьютера числа типа 0.99...99 и 1.00...01 это разные числа. Подтверждение
Код: (vala) [Выделить]
void main()
{
var a = 0.1;
var b = 0.2;
stdout.printf(@"$a + $b = $(a + b)");
}
Вывод0.10000000000000001 + 0.20000000000000001 = 0.30000000000000004Как нам сравнивать числа?
Код: (vala) [Выделить]
void main()
{
var a = 0.1;
var b = 0.2;
if(-1E-2 < a + b - 0.3 < 1E-2)
{
stdout.printf("Равно\n");
}
else
{
stdout.printf("Не равно\n");
}
}
Vala поддерживает форму записи a < b < c в отличии от многих других языков программирования. Пока это эксперементальная фича. Собирать такvalac имя\ файла.vala --enable-experimentalЗаписывать так результат - с_чем_сравнить1E-2Означает 0.01.
Код: (vala) [Выделить]
void main()
{
var r = 1/2;
stdout.printf(@"$r\n");
}
Что выведет?0Почему? Если забыли повторите урок №2. Ещё один аспект
Код: (vala) [Выделить]
void main()
{
int a = int.MAX;
stdout.printf(@"$a\n");
a++;
stdout.printf(@"$a\n");
}
Что выведет? У меня вывел 2147483647
-2147483648
Почему? Произошло переполнение. Один из извесных примеров этой ошибки - поведение Ганди в Civilization.
(Нажмите, чтобы показать/скрыть)
На этом пока всё.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Синтаксический сахар: строки
« Ответ #13 : 15 Июля 2015, 16:22:52 »
Сейчас мы рассмотрим немного синтаксического сахара, связанного со строками. В Vala типизация строгая, а значит такой пример не пройдёт.
Код: (vala) [Выделить]
var n = 5;
var s = "число " + n;
Нужно писать так
Код: (vala) [Выделить]
var n = 5;
var s = "число " + n.to_string();
В Vala это можно сделать гораздо короче:
Код: (vala) [Выделить]
var n = 5;
var s = @"число $n";
Подстановка значения поля переменной:
Код: (vala) [Выделить]
class Apple {
    public int size;
    public Apple() {
        size = 7;
    }
}

void main() {
    var a = new Apple();
    var s = @"Размер яблока равен $(a.size)см";
}
Использования значения функции:
Код: (vala) [Выделить]
int b(ref int c)
{
    c++;
    return c + 8;
}

void main() {
    int c = 9;
    stdout.printf(@"$(b(ref c)) $c\n");
}
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн alsoijw

  • Автор темы
  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Регулярные выражения
« Ответ #14 : 12 Сентября 2015, 00:35:17 »
Несколько слов о регекспах. Объявить переменную можно так
Код: (vala) [Выделить]
var var_name = /regex/;Что мы видим? Регулярные выражения из коробки. Можно скопипастить выражение из баша не задумываясь об экранировании. Например следующий код будет Проверять содержит ли строка точку.
Код: (vala) [Выделить]
void main() {
if(/\./i.match("test.")) {
stdout.printf("true\n");
}
}
Если бы мы писали к примеру на си, то регексп нужно было бы записать так "\\.". Елси у вас есть программа на другом языке то менять запись не обязательно. А ещё этот пример покажет как заменять части строк.
Код: (vala) [Выделить]
void main() {
try {
var quote = "10. 11. 12.";
var regex = new Regex("\\."); //Не забываем экранировть слеш
var result = regex.replace(quote, quote.length, 0, ",");
stdout.printf(result);
} catch (RegexError e) {
stdout.printf ("Error: %s\n", e.message);
}
}
« Последнее редактирование: 11 Декабря 2016, 00:15:26 от alsoijw »
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

 

Страница сгенерирована за 0.056 секунд. Запросов: 25.