#java #arrays #multidimensional-array #switch-statement #case
#java #оператор переключения #константа времени компиляции
Вопрос:
Я создаю анализатор выражений для калькулятора. Выражения будут содержать переменную, например, пользователь может ввести «x 2» или «y ^ 2». У меня есть оператор switch, и один из случаев в операторе switch выполняет определенное действие при обнаружении переменной:
case variableSymbol:
if (expression.length() == 1)
{
rangeResult = x1;
break outer;
}
varFlag = true;
varPos = expresPos;
break;
Первоначально я жестко запрограммировал значение ‘x’ в приведенном выше случае, но я хотел бы предоставить пользователям выбор относительно того, какую переменную они используют, поэтому добавил параметр char в функцию синтаксического анализа и назвал его variableSymbol .
Это параметры для функции:
public static ArrayList<Double> parseRange(String expression, char variableSymbol, double x1, double x2, double step)
Но Java не допускает переменные в качестве регистров в операторах switch. Есть ли какой-либо способ обойти это? Решения, которые позволяют избежать перезаписи оператора switch, являются лучшими, поскольку он имеет длину в несколько сотен строк.Спасибо за вашу помощь.
Комментарии:
1. Во-первых, несколько сотен строк switch-case нуждаются в немедленном рефакторинге (просто для того, чтобы быть такими длинными). Во-вторых, вы можете использовать
if-else
вместо этого, если значение неизвестно во время компиляции. Но опять же, вашif-else
код также вырастет до ста строк кода.. Так что лучше исправить свой дизайн.2. Ваш оператор switch имеет длину в несколько сотен строк ?!?!? Я бы определенно переосмыслил ваш дизайн и предложил лучшее решение.
3. Как насчет создания некоторого класса оператора и фабрики, которые вы передаете оператору? Таким образом, это будет класс operator, который будет содержать логику внутри вашего оператора case. Это упростит читаемость кода и сократит расходы на обслуживание.
4. Я рассмотрю рефакторинг кода, но большинство операторов необходимы. Калькулятор предназначен для оценки интегралов и производных, поэтому пользователи должны иметь возможность вводить все тригонометрические функции, а также экспоненциальный функционал, натуральный логарифм и логарифмическую базу 10, и он также должен иметь возможность выполнять базовые арифметические операции с этими функциями, поэтому я не думаю, что я мог бы сделатьэто короче
Ответ №1:
Нет, это невозможно и не имеет смысла для switch
случая; то, что вы хотите, может быть достигнуто с if-else
помощью . Причина в том, что switch обычно реализуется с помощью справочных таблиц, что более эффективно, чем if-else
; но для достижения этого необходимо настроить ветвление во время компиляции.
Комментарии:
1. Спасибо вам за вашу помощь. Было бы разумно использовать оператор if в одном из случаев? Случаи, предшествующие регистру variableSymbol, все падают, поэтому должна быть возможность сказать, if( expresChar == variableSymbol ){ foo; } . Но не слишком ли это большая халтура
2. Я бы, вероятно, использовал сопоставление с шаблоном (см. Класс сканера); или, если язык должен быть более сложным, генератор синтаксического анализа, такой как ANTLR или JavaCC. If-else или switch хороши только в тривиальных случаях.