008 Операторы
Операторы в Zephir похожи на их аналоги в PHP и также себя ведут.
Арифметические операторы.
Поддерживаемые операторы:
| Оператор | Пример |
| Приведение к отрицательному | -a |
| Сложение | a + b |
| Вычитание | a - b |
| Умножение | a * b |
| Деление | a / b |
| Модуль | a % b |
Операторы сравнения
Операции сравнения зависят от типа сравниваемых переменных, например если оба операнда динамические (var), результат будет таким же как и в PHP:
| a == b | Равенство | TRUE если a равно b после приведения типов. |
| a === b | Идентичность | TRUE если a равно b, и операнды одного типа. |
| a != b | Не равны | TRUE если a не равно b после приведения типов. |
| a <> b | Не равны | TRUE если a не равно b после приведения типов. |
| a !== b | Не идентичны | TRUE если a не равно b, или операнды разных типов. |
| a < b | Меньше | TRUE если a строго меньше b. |
| a > b | Больше | TRUE если a строго больше b. |
| a <= b | Меньше, или равно | TRUE если a меньше, или равно b. |
| a >= b | Больше, или равно | TRUE если a строго больше, или равно b. |
Пример:
if a == b {
return 0;
} else {
if a < b {
return -1;
} else {
return 1;
}
}
Логические опреаторы
Поддерживаемые операторы:
| Операция | Пример |
| И | a && b |
| Или | a || b |
| Отрицание | !a |
Пример:
if a && b || !c {
return -1;
}
return 1;
Побитовые операторы
Поддерживаемые операторы:
| Операция | Пример |
| И | a & b |
| Или | a | b |
| Исключающее или | a ^ b |
| Отрицание | ~a |
| Сдвиг влево | a << b |
| Сдвиг вправо | a >> b |
Пример:
if a & SOME_FLAG {
echo "has some flag";
}
Вы узнаете больше о сравнении динамических переменных в php документации.
Тернарный оператор
Zephir поддерживает тернарный оператор, как в C или PHP.
let b = a == 1 ? "x" : "y"; // в b будет присвоен "x", если a равно 1 в противном случае "y"
Специальные операторы
Поддерживаемые операторы:
Empty
- Empty позволяет узнать пусто ли выражение. Под ‘пусто’ подразумевается выражение возврашающее:
-
- null
- пустую строку
- пустой массив
let someVar = "";
if empty someVar {
echo "is empty!";
}
let someVar = "hello";
if !empty someVar {
echo "is not empty!";
}
Isset
Проверяет, существует ли индекс у массива, или свойство у объекта:
let someArray = ["a": 1, "b": 2, "c": 3];
if isset someArray["b"] { // проверим, есть ли у массива индекс "b"
echo "yes, it has an index 'b'\n";
}
Использование ‘isset’ возможно в return-конструкциях:
return isset this->{someProperty};
Учтите, что ‘isset’ в Zephir работает скорее как array_key_exists в PHP. То есть оператор вернет true даже если значение равно null.
Fetch
Оператор ‘fetch’ создан для сокращения популярной в PHP конструкции:
<?php
if (isset($myArray[$key])) {
$value = $myArray[$key];
echo $value;
}
В Zephir тот же код будет можно написать так:
if fetch value, myArray[key] {
echo value;
}
‘Fetch’ вернет true, если в массиве есть что-то по ключу ‘key’ и тогда в ‘value’ будет присвоенно значение.
Typeof
Этот оператор проверяет Тип переменной. ‘typeof’ может использоваться с оператором сравнения:
if (typeof str == "string") { // or !=
echo str;
}
Он также может работать как функция PHP 'gettype’.
return typeof str;
Будьте осторожны, если вы хотите проверить, является ли объект "вызываемым", вы всегда должны использовать "typeof" в качестве оператора сравнения, а не функции.
Подсказки Типов
Zephir всегда пытается проверить, реализует ли объект методы и свойства, вызываемые/доступные для переменной, которая выводится как объект:
let o = new MyObject(); // Zephir проверяет, реализован ли «myMethod» в MyObject o->myMethod();
Однако из-за динамизма, унаследованного от PHP, иногда нелегко узнать класс объекта, поэтому Zephir не может эффективно создавать отчеты об ошибках. Подсказка типа сообщает компилятору, какой класс связан с динамической переменной, позволяющей компилятору выполнять больше проверок компиляции:
// Сообщает компилятору, что "o" // является экземпляром класса MyClass let o = <MyClass> this->_myObject; o->myMethod();
Подсказки прогнозирования ветвлений
Что такое прогнозирование ветвлений? Для подробного описания это понятия обратитесь к статье Игоря Островского или описанию на Wikipedia. В окружениях, где производительность является очень важной составляющей, может оказаться полезным использование подсказок при прогнозировании ветвлений.
Рассмотрим следующий пример:
let allPaths = [];
for path in this->_paths {
if path->isAllowed() == false {
throw new App\Exception("Some error message here");
} else {
let allPaths[] = path;
}
}
Авторы кода, приведенного выше, заранее знают, что условие, которое выбрасывает исключение, вряд ли произойдет. Это означает, что в 99.9% случаев наш метод выполняет эту проверку в холостую – условие вероятно никогда не будет оцениваться как истинное. Но для процессора, обычно, это сложно понять, поэтому мы могли бы ввести здесь подсказку:
let allPaths = [];
for path in this->_paths {
if unlikely path->isAllowed() == false {
throw new App\Exception("Some error message here");
} else {
let allPaths[] = path;
}
}