fenom/docs/ru/operators.md

310 lines
18 KiB
Markdown
Raw Permalink Normal View History

2014-08-02 00:24:14 +04:00
Операторы
2014-08-01 12:12:19 +04:00
=========
2014-08-02 00:24:14 +04:00
### Арифметические операторы
2014-08-01 12:12:19 +04:00
2014-08-02 00:24:14 +04:00
Все же помнят арифметику?
* `-$a` - отрицание знака, смена знака `$a`.
* `$a + $b` - сложение, сумма `$a` и `$b`.
2014-08-23 12:23:04 +04:00
* `$a - $b` - вычитание, разность `$a` и `$b`.
2014-08-02 00:24:14 +04:00
* `$a * $b` - умножение, произведение `$a` и `$b`.
* `$a / $b` - деление, частное от деления `$a` на `$b`.
* `$a % $b` - деление по модулю, целочисленный остаток от деления `$a` на `$b`.
2014-08-01 12:12:19 +04:00
```smarty
{$a + $b * $c/$d - $e*5 + 1e3}
```
2014-08-02 00:24:14 +04:00
### Логические операторы
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
* `$a || $b` - логичесое ИЛИ, TRUE если или `$a`, или `$b` TRUE.
* `$a && $b` - лигическое И, TRUE если и `$a`, и `$b` TRUE.
* `!$a` - отрицание, TRUE если `$a` не TRUE.
* `$a or $b` - логическое ИЛИ, TRUE если или `$a`, или `$b` TRUE.
* `$a and $b` - логическое И, TRUE если и `$a`, и `$b` TRUE.
* `$a xor $b` - исключающее или, TRUE если `$a`, или `$b` TRUE, но не оба.
2014-08-01 12:12:19 +04:00
```smarty
{if $b && $c} ... {/if}
```
2014-08-03 17:00:30 +04:00
Смысл двух разных вариантов для операторов `and` и `or` в том, что они работают с различными приоритетами.
2014-08-02 00:24:14 +04:00
### Операторы сравнения
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
Операторы сравнения, как это видно из их названия, позволяют сравнивать между собой два значения.
* `$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` после преобразования типов.
2014-08-01 12:12:19 +04:00
```smarty
{if $b >= 5} ... {/if}
```
2014-08-02 00:24:14 +04:00
В случае, если вы сравниваете число со строкой или две строки, содержащие числа, каждая строка будет преобразована в число, и сравниваться они будут как числа.
2014-08-03 17:00:30 +04:00
```smarty
{if 0 == "a"} {* 0 == 0 -> true *} {/if}
{if "1" == "01"} {* 1 == 1 -> true *} {/if}
{if "10" == "1e1"} {* 10 == 10 -> true *} {/if}
{if 100 == "1e2"} {* 100 == 100 -> true *} {/if}
```
2014-08-02 00:24:14 +04:00
Преобразование типов не происходит при использовании `===` или `!==` так как в этом случае кроме самих значений сравниваются еще и типы.
2014-08-03 17:00:30 +04:00
**Таблица сравнения различных типов:**
| Тип операнда 1 | Тип операнда 2 | Результат |
|-------------------|-------------------|-----------|
2014-08-23 12:23:04 +04:00
| null или строка | строка | NULL преобразуется в "", числовое или лексическое сравнение |
| булев или null | что угодно | Преобразуется в bool, FALSE < TRUE |
| объект | объект | Встроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, объекты одного класса - сравниваются свойства тем же способом, что и в массивах |
| строка или число | строка или число | Строки переводятся в числа, обычная математика |
| массив | массив | Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений |
| объект | что угодно | object всегда больше |
| массим | что угодно | array всегда больше |
2014-08-03 17:00:30 +04:00
2014-08-02 00:24:14 +04:00
### Побитовые операторы
Побитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.
2014-08-01 12:12:19 +04:00
2014-08-02 00:24:14 +04:00
* `$a | $b` - битовое ИЛИ, устанавливаются те биты, которые установлены в `$a` или в `$b`.
* `$a & $b` - битовое И, устанавливаются только те биты, которые установлены и в `$a`, и в `$b`.
* `$a ^ $b` - битовое исключающее ИЛИ, устанавливаются только те биты, которые установлены либо только в `$a`, либо только в `$b`, но не в обоих одновременно.
* `~$a` - битовое отрицание, устанавливаются те биты, которые не установлены в `$a`, и наоборот.
* `$a << $b` - битовый сдвиг влево, все биты переменной `$a` сдвигаются на `$b` позиций влево (каждая позиция подразумевает "умножение на 2")
* `$a >> $b` - битовый сдвиг вправо, все биты переменной `$a` сдвигаются на `$b` позиций вправо (каждая позиция подразумевает "деление на 2")
2014-08-01 12:12:19 +04:00
```smarty
{if $a & 1} {var $b = 4 | $flags} {/if}
```
2014-08-03 17:00:30 +04:00
### Оператор присваивания
Базовый оператор присваивания обозначается как `=`. На первый взгляд может показаться, что это оператор "равно".
На самом деле это не так. В действительности, оператор присваивания означает, что левый операнд получает значение правого выражения,
(т.е. устанавливается значением).
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
В дополнение к базовому оператору присваивания имеются "комбинированные операторы" для всех бинарных арифметических операций и строковых операций,
которые позволяют использовать некоторое значение в выражении, а затем установить его как результат данного выражения.
То есть выражение `$a = $a + 2` может быть записано как `$a += 2`.
* `$a = $b` - присвоение
* `$a += $b` - присвоение с добалением.
* `$a -= $b` - присвоение с вычитанием.
* `$a *= $b` - присвоение с умножением.
* `$a /= $b` - присвоение с делением.
* `$a %= $b` - присвоение с делением по модулю.
* `$a &= $b` - присвоение с битовыйм И.
* `$a |= $b` - присвоение с битовыйм ИЛИ.
* `$a ^= $b` - присвоение с битовыйм исключением ИЛИ
* `$a <<= $b` - присвоение с битовым сдвигом влево.
* `$a >>= $b` - присвоение с битовым сдвигом врпаво.
2014-08-01 12:12:19 +04:00
```smarty
{set $b |= $flags}
2014-08-01 12:12:19 +04:00
```
2014-08-03 17:00:30 +04:00
### Операторы инкремента и декремента
Fenom поддерживает префиксные и постфиксные операторы инкремента и декремента в стиле PHP или C.
**Замечание:**
Операторы инкремента/декремента не влияют на булевы значения. Декремент NULL также не даст никакого эффекта, однако инкремент даст значение 1.
* `++$a` - префиксный инкремент, увеличивает $a на единицу, затем возвращает значение $a.
* `$a++` - постфиксный инкремент, возвращает значение $a, затем увеличивает $a на единицу.
* `--$a` - префиксный декремент, уменьшает $a на единицу, затем возвращает значение $a.
* `$a--` - постфиксный декремент, возвращает значение $a, затем уменьшает $a на единицу.
### Строковые операторы
2014-08-03 17:00:30 +04:00
2014-08-23 12:23:04 +04:00
Оператор объединения `~` возвращает строку, представляющую собой соединение левого и правого аргумента.
2014-08-03 17:00:30 +04:00
2015-01-02 22:44:23 +03:00
* `$a ~ $b` - возвращает результат объединения сток `$a` и `$b`
* `$a ~~ $b` - возвращает результат объединения сток `$a` и `$b` через пробел
* `$a ~= $b` - присвоение с объединением
2014-08-03 17:00:30 +04:00
2016-04-12 12:28:57 +03:00
Примеры
```smarty
{"A" ~ "B"} -> AB
{"A" ~~ "B"} -> A B
{add $v = "A"}
{set $v ~= "B"}
{$v} -> AB
```
### Оператор интервала
Оператор `..` позволяет создать массив данных, не выходящих за указанные пределы.
```smarty
{set $a = 1..4}
```
создаст массив `[1,2,3,4]`
```smarty
{set $a = 'a'..'f'}
```
создаст массив `['a','b','c','d','e','f']`
```smarty
{set $a = 'a'|up..'f'|up}
```
создаст массив `['A','B','C','D','E','F']`
```smarty
{set $a = $min..$max}
```
2017-07-31 07:21:56 +03:00
создаст массив из значений где первый (минимальный) элемент будет иметь значение `$min`,
а максимальный (последний) элемент будет иметь значение `$max`
**Замечание:**
ограничения должны быть одного типа, интервал `1..'f'` преобразует `f` в `0` и будет сгенерировано `[1,0]`
2014-08-03 17:00:30 +04:00
### Тернарные операторы
Еще одним условным оператором являются тернарные операторы `?:` и `!:`.
Выражения `(expr1) ? (expr2) : (expr3)` и `(expr1) ! (expr2) : (expr3)` интерпретируется как `expr2`, если `expr1` имеет значение TRUE, или как `expr3` если `expr1` имеет значение FALSE.
Тернарый оператор `?:` проверяет условие `expr1` на не "пустое" значение, то есть `expr1` при конвертирование в булевое значение должен вернуть TRUE.
Следующие значения воспринимаются как пустые:
* "" (пустая строка)
* 0 (целое число)
* 0.0 (дробное число)
* "0" (строка)
* NULL
* FALSE
* array() (пустой массив)
* переменная не объявлена
* элемента массива не существует
* свойство объекта не существует
```smarty
{$request.action ? $request.action : 'default'}
```
Пример выше стоит интерпретировать так: если `$request.action` не пустое то вернуть `$request.action` иначе вернуть `default`.
Приведенный пример можно записать в упрощенном формате:
```smarty
{$request.action ?: 'default'}
```
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
Тернарый оператор `?:` проверяет условие `expr1` на существование и относится больше к работе с переменными,
то есть переменная в выражении `expr1` должна существовать даже если она "пустая", но не NULL.
Данный оператор не имеет значения если `expr1` функция или метод, так как в этом случае всегда будет TRUE.
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
```smarty
{$request.action ! $request.action : 'default'}
```
Пример выше стоит интерпретировать так: если переменна я `$request` существует, является массивом и существует ключ `$request.action` то вернуть `$request.action` иначе вернуть `default`.
Приведенный пример можно записать в упрощенном формате:
```smarty
{$request.action !: 'default'}
```
2014-08-01 12:12:19 +04:00
2014-08-23 12:23:04 +04:00
Как видно, оператор `:?` более расширенный чем `:!` и включает в себя функциональность оператора `!:`.
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
Для упрощения понимания можно подвести итог:
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
* `$a ? $b : $c` - вернет `$b` если `$a` не пустое, иначе вернет `$c`.
* `$a ! $b : $c` - вернет `$b` если `$a` существует, иначе вернет `$c`.
2020-04-27 09:10:55 +03:00
* `$a ?: $b` - вернет `$a` если `$a` не пустое, иначе вернет `$b`.
* `$a !: $b` - вернет `$a` если `$a` существует, иначе вернет `$b`.
2014-08-01 12:12:19 +04:00
```smarty
{var $a = true}
2014-08-03 17:00:30 +04:00
{$a ? 5 : 10} {* вернет 5 *}
2014-08-01 12:12:19 +04:00
{var $a = false}
2014-08-03 17:00:30 +04:00
{$a ? 5 : 10} {* вернет 10 *}
2014-08-01 12:12:19 +04:00
```
2014-08-03 17:00:30 +04:00
### Операторы проверки
Оператор проверки это упрощенный тернарный оператор от которого осталась только часть проверки без возвращаемых вариантов.
2014-08-23 12:23:04 +04:00
Суть операторов — быстро произвести проверку на не пустое значение и существование пременной.
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
* `$a?` - вернет `TRUE` если `$a` не пустое
* `$a!` - вернет `TRUE` если `$a` существует
2014-08-01 12:12:19 +04:00
```smarty
2014-08-03 17:00:30 +04:00
{if $a?} {* вместо {if !empty($a)} *}
{if $a!} {* вместо {if isset($a)} *}
2014-08-01 12:12:19 +04:00
```
2014-08-03 17:00:30 +04:00
### Оператор тестирования
2014-08-01 12:12:19 +04:00
2014-08-23 12:23:04 +04:00
Оператор `is` производит тесты над переменными или выражением. Левый операнд считается тестируемым, а правый операнд — название теста:
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
```smarty
{* проверка переменной на не четность *}
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
{$a is odd}
```
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
Результат тестирования может быть инвертирован с помощью `is not` оператора:
```smarty
2014-08-23 12:23:04 +04:00
{* проверяем переменную что ее значение не является числом *}
2014-08-03 17:00:30 +04:00
{$a is not integer}
```
2014-08-01 12:12:19 +04:00
2014-08-03 17:00:30 +04:00
Список допустимых тестов:
* `$a is integer` - тестирует перменную на тип. Тестом может быть
* `int`, `integer` — целое число
* `bool`, `boolean` — булево значение
* `float`, `double`, `decimal` - дробное число
* `array` — массив
* `object` — объект
* `scalar` — скалярное значение (не массив и не объект)
* `string` — строка
* `callback`, `callable` — функция
* `number`, `numeric` — число, в общем понимании
2014-08-23 12:23:04 +04:00
* `$a is iterable` - тестирует переменную на возможность итеративного обхода (для `foreach`).
2014-08-03 17:00:30 +04:00
* `$a is template` - переменная `$a` содержит название существующего шаблона.
* `$a is empty` - переменная пустая.
* `$a is set` - переменная существует.
* `$a is even` - переменная `$a` имеет четное значение.
* `$a is odd` - переменная `$a` имеет не четное значение.
* `$a is MyClass` или `$a is \MyClass` - переменная `$a` является сущностью класса `MyClass`
* `$a is $b` - `$a` тождественна `$b`
### Оператор присутствия
2014-08-23 12:23:04 +04:00
Оператор `in` проверяет присутствие скалярного значения слева в массиве или строке справа.
2014-08-03 17:00:30 +04:00
Результат тестирования может быть инвертирован с помощью `not ni` оператора.
* `$a in list $b` - значение `$a` содержится в массиве значений `$b`
* `$a in keys $b` - массив `$b` имеет ключ `$a`
* `$a in string $b` - значение `$a` содержится в `$b` как подстрока.
* `$a in $b` - значение `$a` содержится в `$b`, где `$b` может быть строкой, обычным или ассоциативным массивом.
Этот вариант долгий так как требуется проверить типы переменной `$b`.
2014-08-23 12:23:04 +04:00
Однако если вместо $b явно задан массив или строка то оператор сам адаптируется для быстрого поиска.
2014-08-01 12:12:19 +04:00
```smarty
{'df' in 'abcdefg'}
{5 in [1, 5, 25, 125]}
{99 in keys [1, 5, 25, 99 => 125]}
2014-08-23 12:23:04 +04:00
```