Не так давно я решил начать изучать Perl6, даже не смотря на то, что фактически полностью работающего компилятора ещё нету. Подумал что можно смотреть Synopsis'ы, смотреть что из написанного в них уже работает, и изучать как именно это работает на различных примерах. Этим я и начал заниматься, попутно записывая себе в блокнот результаты различных манипуляций с переменными.
И вот в качестве своего первого поста я решил поделиться своими познаниями: тем, что обычно авторы материала оставляют на самостоятельную «проработку» — ответы на вопросы по типу «а что будет если ...» или «а что из себя это представляет в языке».
В этой статье Я опишу какие основные типы данных есть в этом языке и частично затрону вопрос о контекстах — одной из основных особенностей языка Perl.
Виды переменных и типы их возможных значений.
В Perl6 имеется 3 основных вида переменных: Скаляры, Массивы, Хэши.
Для объявления какой либо переменной используется ключевое слово my — объявление локальной переменной, our — для обяъвления глобальной переменной (Это не единственные способы объявления переменных, но пока что хватит).
- Скаляры.
Скаляры, это переменные, которые могут содержать единственное значение: Число, строку, булево значение, ссылку.
Скалярные переменные объявляются с использование знака '$'. Переменные a, b и c объявляются как $a, $b и $c соотвественно. Так же переменные можно сразу же инициализировать значением.
Напримерmy $scalarVar; my ($var1, $var2, $var3); my $newStr = "Это строка"; my $bigNumber = 192958238719732641028368452872938741029834612983412038471293847123641892364; my ($a, $b, $c) = 1, 2, 3; или my ($a, $b, $c) = (1, 2, 3);
Если переменной при объявлении было присвоено значение одного типа например число, то в любой момент переменной может быть присвоена строка, или любой другой тип данных.
Напримерmy $scalarVar; $scalarVar = 'Строка'; $scalarVar = 25; $scalarVar = True;
Основные типы данных:
- Целые числа.
Целые числа представляются типом Int(). Если число по количеству разрядов превышает максимальное количество разрядов типа Int() то оно автоматически приводится к типу Num(), которое может без округлений держать целое число любой длины (Я предполагаю что любой длины, так как один раз ради эксперимента я получил число, длиною в 300 тысяч цифр). Для записи слишком больших чисел можно использовать символ '_' для визуального отделения по несколько цифр в числе. Например1_000_000, 1_0_0_0; 1_00_0
, однако лучше последние два варианта не использовать; - Дробные числа
Дробное число представляется типом Rat() или Num() в зависимости от их значения. Числа могут иметь вид42.01, 10e-5
. При присвоении переменной слишком длинных чисел perl6 может округлять дробную часть, но целую часть держит без изменений, какой бы длинной она не была (Опять же я не уверен в этом, но мои эксперименты подсказывают что будет именно так). Если в в результате вычислений получается очень большое дробное число, то результат может быть возвращен как значение Inf, которое является значением типа Num(). - Строки
В качестве строки может быть любой набор uncode-символов, ограниченный одинарными кавычками (') или двойными ("). Разница между ними в том, что в первом случае не происходит подстановка переменных а так же спец символов (таких как n, t). Если строка записана как'f ф n 1'
то при выводе все эти символы будут показаны без изменений. Если же написать"f ф n 1"
то на экране окажутся две строки: 'f ф ' и строка ' 1'.
'n' Это символ перехода на новую строку. - Булево значение
Это значения True и False (Обязательно с большой буквы!), имеющие тип Bool(). - Ссылки
Переменная данного типа указывает на существующий объект. С помощью ссылки можно проводить точно такие же действия как и с самим объектом, на которую она указывает (например обращение к элементу массива).
Самое главное:$a = 10; $b = $a;
В данном случае переменной $b присваивается ссылка на переменную $a. Если вывести на экран значение переменной $b, то по ссылки автоматически будет взято значение переменной $a, НО если переменной $b присвоить новое значение
$b=5;
то значение 5 будет записано вместо ссылки на переменную $a, а не в саму переменную $a. Т.е. теперь $b будет содержать не ссылку, а просто число. - Пара 'Ключ-значение'
Этот тип имеет имя Pair(). Конструктором пар является '=>'. Например(1=>'a')
создает пару, где ключем является 1, а значение по данному ключу — 'a'. Причем возможными значениями ключей являются строки ( в данном случае 1 была автоматически приведена к строковому типу), а значениями по ключу могут быть любые скаляры.
- Целые числа.
- Массивы
В Perl6 массивы динамические, т.е. при их инициализации не нужно указывать максимальный размер, т.к. память выделяется по мере добавления новых элементов. Элементами массива являются любые скаляры и скалярные переменные. В массивах индекс элемента зависит от позиции при объявлении. Конструктором массива является запятая. Например выражение('a', 502, "str")
конструирует массив размером в 3 элемента (круглые скобки не обязательны). Индексы у элементов начинаются с нуля. т.е. нулевым элементом массива является 'a', под индексом 1 находится число 502, под индексом 2 находится «str». Типы скаляров не обязательно должны быть одинаковыми. Для генерации ссылки на массив используются квадратные скобки. Например['a', 502, "str"]
возвращает ссылку на новый массив, которую можно присвоить скалярной переменной.
Имя массива должно начинаться с символа '@'. Например@mass, @colors, @names
. Причем $names и
@names
являются разными переменными.
Массивы могут содержать любое количество элементов различного типа.
Примеры использования:@arr = ('a', 502, "str"); @arr2 = (10, False, True, $scalarVar);
Для обращения к элементам массива используются квадратные скобки:
Например выражение @arr2[0] вернет 10, а @arr2[3] вернет не переменную $scalarVar а её значение, которое было на момент создания массива. Чтобы получить значение переменной $scalarVar записывать в массив нужно было ссылку на эту переменную:@arr2 = (10, False, True, $scalarVar);
Если изначальный размер массива 2:@arr = (1, 2);
и мы хотим задать значение элемента под индексом 5 (Например @arr[5] = 'new elem') то массив будет расширен до 6 элементов, а все добавленные элементы кроме @arr[5] будут неинициализированы ( Тип этого значения — Any() ). - Хэши
Хэши представляют собой таблицу соотвествий, когда каждому ключу ставится в соотвествии одно значение. Значениями элементов хэша являются любоые скаляры а ключами являются строки.
Имя хэшей должно начинаться с символа '%':my %hash = ('key1'=>'value1', '2'=>200, 'key10'=>True);
Если присвоить хэшу массив, то элементы массива будут попарно составлять элемент хэша:
my @mas = ('a, 1, 'b', 2); my %hash = @mas;
В результате этого в переменной %hash будет храниться ('a'=>1, 'b'=>2);
Для обращения к элементам хэша используются фигурные скобки:
%hash{'a'} = 'new value';
Для добавления нового элемента хэша достаточно просто присвоить значение по новому ключу:
%hash{'new elem'} = 255;
Если в качестве ключа использовать число
%hash{1000} = 20;
то число конвертируется в строку, поэтому если в хэше уже есть элемент с ключем '1000', то при занесении значения по числовому ключу уже существующее значение перезапишется.
Так же хэш можно конструировать из пар:$a = ('a'=>1); $b = ('b'=>2); %hash = $a, $b, 'c'=>3;
Контексты
Перейдем теперь к контекстам.
Perl 6 контекстно зависимый, это означает, что при различных условиях использования переменной, могут возвращаться различные значения. Прежде всего контекст определяется тем, какой именно переменной будет присваиваться значение:
$a =… — устанавливается скалярный контекст, @a =… устанавливается списочный контекст и т.д.
Имеются следующие контексты:
- Скалярный контекст
Скалярный контекст задается с помощью конструкции $(), где внутри скобок указывается выражение, результат которого будет интерпретироваться в скалярном контексте.
При использовании массивов в скалярном контексте вместо самого массива возвращается ссылка на данный массив, которую уже можно использовать, как имя массива (Например использовать операцию получения элемента массива).
При использование хэшей в скалярном контексте возвращается ссылка на хэш.
Более конкретные виды контекстов это:- Числовой контекст
Числовой контекст задается с помощью конструкции +(). Если в результате выражения, интерпретируемого в данном контексте, получается не числовой результат, то будет произведено приведение к числовому типу, и если в результате приведения появится ошибка, то работа скрипта останавливается. - Строковый контекст
Строковый контекст задается с помощью конструкции ~(). Обычно к строковому типу можно привести любое значение, поэтому проблем с данным контекстом не предвидется - Логический контекст
Логический контекст задается с помощью конструкции ?(). Результат выдается по правилам приведения к логическому типу.
- Числовой контекст
- Списочный контекст
Списочный контекст задается с помощью конструкции @(). Пример создания массивов:@a1 = (1, 2); @a2 = (3, 4); @a3 = (5, 6);
Однако если написать следующую строку
@b = (@a1, @a2, @a3);
то в результате, получится одномерный массив @b, который будет выглядить как
(1, 2, 3, 4, 5, 6)
, а не двумерный массив, выглядящий как([1, 2], [3, 4], [5, 6])
. Получается это из-за того, что списочный контекст «сливает» все переданные ему массивы и хэши в один большой массив. Чтобы получить многомерный массив, необходимо передавать в конструктор не сами массивы, а ссылки на них:@b = (@a1, @a2, @a3)
Если в списочном контексте используется скалярное значение, то в результате получается одноэлементный массив, состоящий из этого скаляра.
Если в списочном контексте используется хэш, то в массив будут скопированы все ключи и значения из хэша в попарном виде:%a = (1=>'a', 2=>'b'); @a = %a; # (1, 'a', 2, 'b')
Важно не путать, чем отличается результат выражения
(1, 2)
от результата выражения[1, 2]
:
в первом случае, получается массив. Если его присвоить скалярной переменной $a = (1, 2) то в итоге в этой переменной будет ссылка на массив, если написать @a = (1, 2) то @a будет массивом из двух элементов.
Во втором случае, $a = [1, 2] так же будет содержать ссылку на массив, но @a = [1, 2] переменная @a будет массивом, состоящим из одного элемента — ссылки на массив (1, 2), т.к. ссылка является скалярным значением, которое и становится единственным элементом массива @a. - Контекст хэша
В контексте хэша из скалярных переменных можно использовать только пары, или ссылки на массивы и хэши (про массивы ниже).
Если в контексте хэша используется массив с нечетным количеством элементов, то скрипт останавливает работу, т.к. при конструировании хэша количество ключей и количество значений не будет совпадать.
Если используется массив с четным количеством элементов, то в итоге получается хэш, в котором ключами являются четные элементы массива (под индексами 0, 2, 4), а значениями являются нечетные элементы массива (под индексами 1, 3, 5)
Для задания контекста хэша используется конструкция %()
В случае если написать$a = [1, 2]; %a = $a;
то в результате будет ошибка! — т.к. хэшу присваивается скалярное значение — ссылка, и получается, что количество ключей не соответсвует количеству значений.
Если же написать:$a = [1, 2]; %a = %($a);
То получается цепочка: ссылка на массив $a используется в хэш-контексте, поэтому берется само значение массива. При приведении типа массива к типу хэша, создается новый хэш (1=>2), и он уже присваивается переменной %a;
Ну вот, на этом мой маленький опыт манипуляций с переменными пока что и ограничивается. Я надеюсь что вы сдесь увидели что-то новое для вас, и интересное. Удачного дня!
Автор: WarFair