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; } }