Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • Changelogs
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    RouterOS
    [Запрос функции]: оператор 'else-if'

    [Запрос функции]: оператор 'else-if'

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    [Запрос функции]: оператор 'else-if', RouterOS
     
    Moustafa
    Guest
    #1
    0
    02.05.2025 00:18:00
    Большая функция: добавить конструкцию else-if в консоль. Синтаксис такой: # RouterOS
    :if (<условие_1>) do={
       <команда>
    } else-if (<условие_2>) do={
       <команда>
    } else-if (<условие_3>) do={
       <команда>
    } else={
       <команда>
    };
     
     
     
    teslasystems
    Guest
    #2
    0
    06.07.2025 13:19:00
    Там отдельно есть обработчик :onerror, так что я не вижу в этом никакого смысла.
     
     
     
    dot02
    Guest
    #3
    0
    04.07.2025 09:41:00
    Определённо +1
     
     
     
    BartoszP
    Guest
    #4
    0
    06.07.2025 07:35:00
    Нужно ли указывать on-error={ ... } для каждого цикла do в if, if-else или достаточно одного для всего выражения?
     
     
     
    Moustafa
    Guest
    #5
    0
    06.07.2025 14:41:00
    @teslasystems Ты прав, @BartoszP. Всё просто: можно использовать do {} on-error={} внутри оператора if. Однако добавлять это отдельно не нужно, потому что это будет конфликтовать с else и else-if (если их добавят в будущем) или не позволит их использовать.
     
     
     
    BartoszP
    Guest
    #6
    0
    06.07.2025 16:06:00
    Не могли бы вы объяснить, как именно должен использоваться on-error для “if”? С другой стороны, если для каждого оператора do требуется свой собственный “on-error” на случай ошибки в конкретной ветке “if”. Если же есть только одно общее выражение, ловящее “on-error”, тогда нужно как-то фиксировать, какая именно ветка вызвала ошибку… Давайте сразу представим конструкцию try/catch. Вся идея, и не только в MT-скриптах, конструкции “else-if” для меня неверна, когда между условиями нет никакой взаимосвязи. Чистый вариант: if условие then  
      набор операторов  
    else  
      другой набор операторов  
    endif — безусловно ведёт к выполнению одной или другой ветки. Если у вас несколько связанных или не связанных “if” и “else if”, то стоит использовать что-то вроде “switch” или “case of”:  

    case of  
     условие#1: набор операторов для условия#1  
     условие#2: набор операторов для условия#2  
     ....  
     условие#N: набор операторов для условия#N  
    end case of  

    Это самообъясняющаяся конструкция, которая не зависит от “сохранённого” состояния предыдущих проверок, применяемых к последующим частям “else-if” в условии, которое надо “держать в голове”, анализируя код:  

    if условие#1 then  
      набор операторов для условия#1  
    else-if условие#2 then  
      набор операторов для условия#2  
    ...  
    else-if условие#N then  
      набор операторов для условия#N  
    endif  

    на самом деле означает:  

    if условие#1 then  
      набор операторов для TRUE(условие#1)  
    else-if условие#2 then  
      набор операторов для условия#2, когда FALSE(условие#1) .and. TRUE(условие#2)  
    ...  
    else-if условие#N then  
      набор операторов для условия#N, когда FALSE(условие#1) .and. FALSE(условие#2) .and. ... FALSE(условие#N-1) .and. TRUE(условие#N)  
    endif  

    по сравнению с более очевидным:  

    cond#1 = проверка#1  
    cond#2 = проверка#2  
    ...  
    cond#N = проверка#N  

    case of  

     TRUE(условие#1) : операторы для условия#1  
     FALSE(условие#1) .and. TRUE(условие#2) : операторы для условия#2  
    ...  
     FALSE(условие#1) .and. ... .and. TRUE(условие#N) : операторы для условия#N  
    end case of  

    Хотя, честно говоря, я сейчас, похоже, открыл ящик Пандоры.
     
     
     
    optio
    Guest
    #7
    0
    06.07.2025 16:43:00
    В большинстве языков программирования есть разница между else-if и switch-case: последний позволяет выполнять блоки для нескольких условий, если блок с условием не прерывается (в некоторых языках нужно явно указывать continue), тогда как else-if чётко указывает условие, чтобы избежать вложенности в else блоке. В RSC даже отсутствуют операторы break / continue для корректной реализации switch-case…
     
     
     
    optio
    Guest
    #8
    0
    06.07.2025 23:05:00
    Под "большинством" я имел в виду большинство современных языков. Окей, некоторые языки могут иметь другую конструкцию для множественной проверки условий или значений, как, например, Rust (match), но есть много других, которые поддерживают множественное совпадение с переходом к следующему варианту (как я уже упоминал, для этого в некоторых нужно явно указать), такие как: разные языки в стиле C, включая JS и TS, Swift, Kotlin, Golang… или скриптовые языки типа Bash, TCL…
     
     
     
    optio
    Guest
    #9
    0
    06.07.2025 23:09:00
    Чёрт с этим форумом... Нажал не ту кнопку «ответить», этот пост выше должен был быть для @BartoszP, а не для @Amm0... Я не могу вставить тот же текст в ответ @BartoszP, даже если удалю старый, потому что он слишком похож... Отстой.
     
     
     
    teslasystems
    Guest
    #10
    0
    07.07.2025 02:34:00
    Для всего оператора это выглядело бы так: :local x true

    :onerror errMsg {
    :if ($x) do={
    :put "x истинно"
    } else={
    :put "x ложно"
    }
    } do={
    :put "Что-то не так, ошибка: $errMsg"
    } @Moustafa :do {} on-error={} устарело (так сказали в поддержке MikroTik) и может не работать в некоторых случаях, избегайте использования, вместо этого используйте :onerror err {} do={}. И я соглашусь, что case или switch были бы лучше. Но в таком случае я предпочёл бы поведение, как в Pascal, то есть после первого совпадения остальные условия не проверяются. Или им нужно добавить команду break и сделать как в C (что менее предпочтительно). Кстати, команда break всё равно нужна! Пользователи просили её много раз, ещё лет 15 назад, и ничего не сделали.
     
     
     
    Moustafa
    Guest
    #11
    0
    09.07.2025 09:55:00
    @teslasystems Откуда у вас информация, что они так сказали? Несмотря на то, что я по-прежнему прошу вас предоставить источники, я до сих пор ежедневно использую :do {} on-error={} вплоть до написания этого ответа, и никаких проблем не испытываю. Не думаю, что это уберут, ведь это считается простым и быстрым способом применения функции onerror. Хотя они похожи, они отличаются по способу работы и реализации. Я вижу, что у каждого из них свой метод.
     
     
     
    teslasystems
    Guest
    #12
    0
    09.07.2025 10:23:00
    Какой источник? Источник — служба поддержки MikroTik, я это сказал. Например, инструмент snmp-get не работает с :do {} on-error={}, только :onerror может с этим справиться. В любом случае, решать вам — использовать или нет, я просто предупредил.
     
     
     
    BartoszP
    Guest
    #13
    0
    06.07.2025 18:07:00
    Черви вылазят. Что значит «на большинстве языков»? С этим можно поспорить. Семейство C: используют «break», чтобы прервать последовательное выполнение следующего кейса. Для меня это просто артефакт планирования как assembler++ в процессе разработки — так легче оптимизировать код с помощью этой конкретной синтаксической конструкции. D, Java: имитируют C, используют «break». Rust: нет последовательного выполнения, один блок операторов на кейс. Python: нет последовательного выполнения, один блок операторов на кейс. Старожилы COBOL, FORTRAN: один оператор на кейс. Ada: нет последовательного выполнения, семейство Pascal (правильнее сказать семьи Algol/Simula): нет последовательного выполнения. Я знаю эти различия. Обратите внимание, что я намеренно назначил результаты check#N в переменные, так как вычисление проверки могло быть неинвариантной операцией. Я написал это в достаточно независимом синтаксисе, чтобы не подразумевать какой-либо конкретный язык. Я также понимаю, что в RSC отсутствует много удобных синтаксических возможностей. Он даже не согласован с синтаксисом «if»: ветка true — это do = {} оператор, а else — отдельный элемент. Было бы логичнее, если бы синтаксис выглядел так:

    if (cond) do = {
    } else do = {
    }
     
     
     
    Amm0
    Guest
    #14
    0
    06.07.2025 19:02:00
    Я не считаю, что там должен быть else-if. Но соглашусь, что switch отсутствует, и это было бы предпочтительнее, чем куча if подряд. «Современные языки» перешли от простого switch к «сопоставлению с образцом», где можно задать что-то для сравнения и указать выражения (в отличии от C, где только значение) для проверки. Лично я считаю, что поддержка «групп» в регулярных выражениях сильно помогла бы избежать длинных цепочек if (и пригодилась бы в каком-нибудь будущем синтаксисе типа else-if/switch/сопоставления с образцом). Если regex может заменить серию if-else, это было бы понятно и удобно.

    Сравнивать с «языками общего назначения» сложно... RouterOS скорее «язык конфигурации», как Cisco TCL, несколько языков для Kubernetes или даже фирменный язык Apple pkl, где if — всего лишь выражение. Наконец, предложенный синтаксис игнорирует, что :if всё ещё команда (функция), так что :if () do={} и последующее за ним что-то, тем более несколько do={}, противоречит множеству правил парсинга RouterOS. Значит, добавлять что-то вроде else-if будет, подозреваю, очень сложно — да и вообще это шаг назад.

    Короче говоря: ставлю минус за ‘else-if’.
     
     
     
    Moustafa
    Guest
    #15
    0
    06.07.2025 19:57:00
    @BartoszP ты можешь использовать on-error внутри if, как в этом примере: :if (<условие>) do={ :do { <команда> } on-error={ <команда> }; } else={ :do { <команда> } on-error={ <команда> }; } Но честно говоря, лучше всего использовать switch case с break и default.
     
     
     
    Amm0
    Guest
    #16
    0
    06.07.2025 20:03:00
    Да. К слову, :if всё ещё остаётся командой (встроенной функцией), так что on-error= — это аргумент команды “if”, как и else={}. Проблема с “else-if” в исходном сообщении в том, что это НЕ аргумент, а новые команды всегда требуют новой строки или точки с запятой (+пробела). И во-вторых, стек решился бы, если бы else-if была отдельной командой — вот почему else-if, вероятно, сложнее, чем какой-нибудь новый :switch.
     
     
     
    Moustafa
    Guest
    #17
    0
    06.07.2025 20:03:00
    @BartoszP @optio @Amm0 Вы правы. Использовать switch-case — это лучший вариант.
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2025 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры