Сбалансированные пары (например, круглые скобки) являются примером языка, который не может быть распознан регулярными выражениями.
Далее следует краткое объяснение математики, почему это так.
Регулярные выражения - это способ определения автоматов с конечным состоянием (сокращенный FSM). Такое устройство имеет конечное количество возможного состояния для хранения информации. То, как это состояние может быть использовано, конкретно не ограничено, но это означает, что существует абсолютное максимальное количество различных позиций, которые он может распознать.
Например, состояние может использоваться для подсчета, скажем, несогласованных левых скобок. Но поскольку количество состояний для такого подсчета должно быть полностью ограничено, то данный FSM может рассчитывать до максимума n -1, где n - это число указывает, что FSM может быть в. Если n , скажем, 10, то максимальное количество несогласованных левых скобок FSM может совпадать, равно 10, пока оно не сломается. Поскольку вполне возможно иметь еще одну левую скобку, нет возможности FSM, который может правильно распознать полный язык совпадающих круглых скобок.
Ну и что? Предположим, вы просто выбрали действительно большой n ? Проблема в том, что в качестве способа описания FSM регулярные выражения в основном описывают все переходы из одного состояния в другое. Так как для любого N для FSM потребуется 2 перехода состояния (одно для сопоставления левой скобки и одно для правильного совпадения), само регулярное выражение должно расти, по крайней мере, с постоянным множителем, кратным n
. Для сравнения, следующий лучший класс языков (контекстно-свободные грамматики) может решить эту проблему совершенно компактным образом. Вот пример в BNF
expression ::= `(` expression `)` expression
| nothing
blockquote>
varargs могли это сделать (в некотором смысле). Кроме этого, должны быть указаны все переменные в объявлении метода. Если вы хотите, чтобы переменная была необязательной, вы можете перегрузить метод, используя сигнатуру, которая не требует параметра.
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}
Это зависит от того, чего вы хотите достичь, varargs или перегрузка метода должны решить большинство сценариев. Вот несколько хороших примеров того, как их использовать:
http://blog.sleekface.com/in/java-core/method-with-optional-parameters/
, но имейте в виду, что не следует чрезмерно использовать перегрузку методов . это вносит путаницу.
Были упомянуты VarArgs и перегрузка. Другой вариант - шаблон Builder, который будет выглядеть примерно так:
MyObject my = new MyObjectBuilder().setParam1(value)
.setParam3(otherValue)
.setParam6(thirdValue)
.build();
Хотя этот шаблон будет наиболее подходящим, когда вам нужны дополнительные параметры в конструкторе.
В Java нет дополнительных параметров. Что вы можете сделать, так это перегрузить функции и затем передать значения по умолчанию.
void SomeMethod(int age, String name) {
//
}
// Overload
void SomeMethod(int age) {
SomeMethod(age, "John Doe");
}
Компилятор должен уметь распознавать, что BigFoo
не может быть преобразовано в IEnumerable
, но это не так. Он просто видит, что это IEnumerable
, и чувствует, что это потенциальный кандидат на перегрузку (даже несмотря на то, что ограничение, которое вы определили, заставляет T
быть IFoo
и int
не может быть преобразовано в IFoo
). Хотя это неудобно, но это не так уж и важно. Просто приведите bigFoo к IFoo
, и компилятор будет доволен:
fooContainer.Add((IFoo)bigFoo);
В качестве альтернативы, вы можете сделать вашу общую перегрузку Add uglier:
public void Add<T, U>(U group)
where T : IFoo
where U : IEnumerable<T>
{
}
В любом случае у вас будет больше ввода, второе решение устранит необходимость для отправки вызовов на Добавить
,
t поддерживают параметры по умолчанию напрямую.
Тем не менее, я написал набор аннотаций JavaBean, и одна из них поддерживает параметры по умолчанию, такие как следующие:
protected void process(
Processor processor,
String item,
@Default("Processor.Size.LARGE") Size size,
@Default("red") String color,
@Default("1") int quantity) {
processor.process(item, size, color, quantity);
}
public void report(@Default("Hello") String message) {
System.out.println("Message: " + message);
}
Процессор аннотаций генерирует перегрузки методов для правильной поддержки этого.
См. http://code.google.com/p/javadude/wiki/Annotations
Полный пример на http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample
.В Java 5.0 появились необязательные параметры. Просто объявите вашу функцию вот так:
public void doSomething(boolean... optionalFlag) {
//default to "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
вы могли бы вызвать с помощью doSomething();
или doSomething(true);
сейчас.