Типы

Zephir динамически и статически типизированный. В этой главе мы выделим поддерживаемые типы и их поведение.

Динамические типы

Динамические переменные точно такие же, как и в PHP. Они могут быть назначены и переназначены в различные типы без ограничений.

Динамическая переменная должна быть объявлена с помощью служебного слова var. Работа с такой переменной очень похожа на то, как мы работаем с переменными в PHP:

var a, b, c;
Инициализировать переменные
let a = "hello", b = false;
Изменить их значения
let a = "hello", b = false;
let a = 10, b = "140";
Выполнить операции с ними
let c = a + b;

Переменные объявленные как динамические, могут иметь восемь типов:

Тип Description
array Массив — это упорядоченная карта. Карта — это тип, который связывает значения с ключами.
boolean Булев тип выражает истинное значение. Он может иметь значения true либо false.
float/double Числа с плавающей точкой. Размер зависит от платформы.
integer Целые числа. Размер целого числа зависит от платформы.
null Специальное значение NULL представляет переменную без значения.
object Абстракция объекта, как и в PHP.
resource Ресурс содержит ссылку на внешний ресурс.
string Строка представляет собой последовательность символов, где символ является одним байтом.

Подробнее об этих типах можно узнать в руководстве PHP.

Array

Реализация массива в Zephir в основном такая же, как и в PHP: упорядоченные карты, оптимизированные для различных целей; Этот тип данных можно трактовать как массив, список (вектор), хэш-таблицу (реализацию карты), словарь, коллекцию, стек, очередь. Возможны и другие трактовки. Много мерные массивы также возможны: в качестве значений массива могут выступать другие массивы.

Синтаксис для определения массивов немного отличается от PHP:

Для определения массивов должны использоваться квадратные скобки
let myArray = [1, 2, 3];
Для определения ключей хэшей необходимо использовать двоеточие
let myHash = ["раз": 1, "два": 2, "три": 3];

В качестве ключей могут использоваться только значения типов long и string:

let myHash = [0: "раз", 1: true, 2: null];
let myHash = ["раз": 7.0, "два": "некоторая строка", "три": false];

Boolean

Булев тип выражает истинное значение. Он может иметь значения true либо false:

var a = false, b = true;

Float/Double

Числа с плавающей точкой (также известные как "вещественные числа"). Литералы с плавающей точкой представляют собой выражения из нуля или более цифр, за которыми следует точка (.), за которой следуют ноль или более цифр. Размер float — платформозависимая величина, хотя максимум ~ 1.8e308 с точностью примерно 14 десятичных цифр является наиболее общим значением (64-битный формат IEEE).

var number = 5.0, b = 0.014;

Числа с плавающей точкой имеют ограниченную точность. Хотя это зависит от системы, как и в PHP, Zephir использует формат двойной точности IEEE 754, который даст максимальную относительную ошибку из-за округления порядка 1.11e-16.

Integer

Целые числа. Размер целого числа зависит от платформы, хотя максимальное значение около двух миллиардов является обычным значением (это 32 битное, знаковое). 64-битные платформы обычно имеют максимальное значение около 9E18. PHP не поддерживает беззнаковые целые, поэтому у Zephir есть это ограничение тоже:

var a = 5, b = 10050;

Целочисленное переполнение

В отличие от PHP, Zephir автоматически не проверяет переполнение целочисленного типа. Точно так же, как и в C, если вы выполняете операции, которые могут возвращать большое число, вы можете использовать такие типы, как unsigned long или float для их хранения:

unsigned long my_number = 2147483648;

Object

Zephir позволяет создавать экземпляры PHP классов, манипулировать PHP объектами, вызывать методы на них, читать константы классов и т.д.:

let myObject = new \stdClass(),
    myObject->someProperty = "некоторое значение";

String

Переменная типа string представляет собой последовательность символов, где символ (char) является одним байтом. Как PHP, Zephir поддерживает только 256-символьный набор и, следовательно, не предлагает поддержку Unicode.

var today = "friday";

В Zephir строковые литералы могут указываться только с помощью двойных кавычек (как в C или Go). Одинарные кавычки зарезервированы для типа данных char.

В строках поддерживаются следующие escape-последовательности:

Последовательность Description
\t Горизонтальная табуляция
\n Перевод строки
\r Возврат каретки
\ Обратная косая черта
\" Двойная кавычка
var today    = "\tпятница\n\r",
    tomorrow = "\tсуббота";

В Zephir строки не поддерживают интерполяцию переменных, как в PHP, вместо этого вы можете использовать конкатенацию:

var name = "peter";

echo "hello: " . name;

Статические типы

Статическая типизация позволяет разработчику объявлять и использовать некоторые типы переменных, доступные в C. Переменные, объявленные как статические, не могут менять свой тип. Тем не менее, они позволяют компилятору делать оптимизацию лучше. Поддерживаются следующие типы данных:

Тип Description
array Структура, которая может использоваться в качестве хеша, карты, словаря, коллекции, стека и т. д.
boolean Булев тип выражает истинное значение. Он может иметь значения true либо false.
char Наименьшая адресуемая единица машины, которая может содержать символ из базового набора.
float/double Тип с плавающей точкой двойной точности. Размер является платформозависимым.
integer Знаковое целое. Размер по крайней мере 16 бит.
long Длинное знаковое целое. Размер по крайней мере 32 бит.
string Строка представляет собой последовательность символов, где символ (char) является одним байтом.
unsigned char Тот же размер, что и char, но гарантированно беззнаковый.
unsigned integer Беззнаковое целое. Размер по крайней мере 16 бит.
unsigned long То же, что и long, но без знака.

Boolean

Булев тип выражает истинное значение. Он может иметь значения true либо false. В отличие от динамического поведения, описанного выше, статические логические типы остаются логическими (true или false), а не тем типом значения, что им присваивается:

boolean a;
let a = true;
автоматически переводится в true
let a = 100;
автоматически переводится в false
let a = 0;
выкидывает ошибку компиляции
let a = "hello";

Char/Unsigned Char

переменная типа char — наименьшая адресуемая единица машины, которая может содержать символ из базового набора (обычно 8 бит). Переменная типа char может быть использована для хранения одного символа в строке:

char ch, string name = "peter";
сохраняет 't'
let ch = name[2];
литералы типа char должны быть заключены в одинарные кавычки
let ch = 'Z';

Integer/Unsigned Integer

целочисленные значения подобны целочисленным аналогам в динамических типах. Значения, присвоенные целым переменным, остаются целыми:

int a;

let a = 50,
    a = -70;
автоматически переводится в 100
let a = 100.25;
автоматически переводится в 0
let a = null;
автоматически переводится в 0
let a = false;
выкидывает ошибку компиляции
let a = "hello";

беззнаковые целые подобны целым числам, но они не имеют знака, это означает, что вы не можете хранить отрицательные числа в таких переменных:

uint a;

let a = 50;
автоматически переводится в 70
let a = -70;
автоматически переводится в 100
let a = 100.25;
автоматически переводится в 0
let a = null;
автоматически переводится в 0
let a = false;
выкидывает ошибку компиляции
let a = "hello";

Тип unsigned integer в два раза больше стандартного integer. Присваивание беззнаковых целых стандартным целым (знаковым) может привести к потере данных:

возможна потеря данных для b
uint a, int b;

let a = 2147483648,
    b = a;

Long/Unsigned Long

переменные типа long в два раза больше, чем integer, поэтому они могут хранить большие числа. Как и с integer, при присваивании значений переменным типа long, они будут автоматически приводиться к этому типу:

long a;

let a = 50,
    a = -70;
автоматически переводится в 100
let a = 100.25;
автоматически переводится в 0
let a = null;
автоматически переводится в 0
let a = false;
выкидывает ошибку компиляции
let a = "hello";

Тип unsigned long похож на long, но он не имеет знака. Это означает, что вы не можете хранить отрицательные числа в таких переменных:

ulong a;

let a = 50;
автоматически переводится в 70
let a = -70;
автоматически переводится в 100
let a = 100.25;
автоматически переводится в 0
let a = null;
автоматически переводится в 0
let a = false;
выкидывает ошибку компиляции
let a = "hello";

Тип unsigned long в два раза больше стандартного long; присваивание данных типа unsigned long стандартному знаковому long может привести к потере данных:

возможна потеря данных для b
ulong a, long b;

let a = 4294967296,
    b = a;

String

Строка представляет собой последовательность символов, где символ является одним байтом. Как и в PHP, этот тип данных поддерживает только 256-символьный набор и, следовательно, не поддерживает использование Юникода.

Когда переменная объявлена как типа string, она никогда не меняет свой тип:

string a;

let a = "";
строковые литералы должны быть заключены в двойные кавычки
let a = "hello";
преобразуется в строку "A"
let a = 'A';
автоматически переводится в ""
let a = null;