Java: инициализировать несколько переменных в цикле инициализации цикла?


92

Я хочу иметь две переменные цикла разных типов. Есть ли способ заставить это работать?

@Override
public T get(int index) throws IndexOutOfBoundsException {
    // syntax error on first 'int'
    for (Node<T> current = first, int currentIndex; current != null; 
            current = current.next, currentIndex++) {
        if (currentIndex == index) {
            return current.datum;
        }
    }
    throw new IndexOutOfBoundsException();
}

Что есть first? Это нигде не заявлено. Это член класса?
extraneon

7
Вы должны принять один ответ ниже
Mr_and_Mrs_D

И, в отличие от C, в Java нет оператора запятой: stackoverflow.com/questions/12601596/… , который позволяет инициализировать (но не объявлять) две переменные разных типов.
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

@Nick Heiner Не могли бы вы отметить один из ответов ниже как принятый?
Джеймс Монгер

Ответы:


105

Инициализацияfor заявления следует правилам деклараций локальных переменных .

Это было бы законно (если глупо):

for (int a = 0, b[] = { 1 }, c[][] = { { 1 }, { 2 } }; a < 10; a++) {
  // something
}

Но попытка объявить отдельные типы Nodeи по intсвоему усмотрению недопустима для объявлений локальных переменных.

Вы можете ограничить объем дополнительных переменных в методах, используя такой блок:

{
  int n = 0;
  for (Object o = new Object();/* expr */;/* expr */) {
    // do something
  }
}

Это гарантирует, что вы случайно не повторно используете переменную в другом месте метода.


10
Кто-нибудь знает, почему разработчики языка реализовали это, казалось бы, ненужное ограничение?
Джефф Аксельрод

@glenviewjeff - это лучше всего задать отдельным вопросом.
McDowell

2
@JeffAxelrod, возможно, по историческим причинам, потому что Java была смоделирована после C ++ ... см. Этот пост: stackoverflow.com/questions/2687392/…
Christophe Roussy

3
+1 за использование блока, я использую их много, все же лучше, чем делать глупые ошибки
Кристоф Русси

18

Тебе это не может понравиться. Либо вы используете несколько переменных одного типа, for(Object var1 = null, var2 = null; ...)либо извлекаете другую переменную и объявляете ее перед циклом for.


9

Просто переместите объявления переменных ( Node<T> current, int currentIndex) за пределы цикла, и все должно работать. Что-то вроде этого

int currentIndex;
Node<T> current;
for (current = first; current != null; current = current.next, currentIndex++) {

а может даже

int currentIndex;
for (Node<T> current = first; current != null; current = current.next, currentIndex++) {

1
Ни то, ни другое не будет компилироваться: вам необходимо инициализировать переменные перед использованием.
unbeli

@unbeli ну, я не занимался ручной компиляцией кода :) Я просто хотел дать идею.
Никита Рыбак

3
@unbeli: Чтобы уточнить: необходимо инициализировать currentIndex. Первое, что делает с ним Никита, - это "currentIndex ++", что, естественно, вызывает вопрос: что делать? current - это нормально, потому что первое использование - установить его на первое.
Джей

Обычно, чтобы лучше писать приращение в цикле for, следует использовать ++ var в качестве обозначения var ++, требуемого от компилятора для дублирования содержимого var, прежде чем увеличивать его, чтобы вернуть его как результат выражения, хотя это никому не нужно. Конечно, компилятор оптимизирует это, но это все равно, что выбрасывать мусор на дорогу, ожидая, пока другие его уберут.
Чаки

5

Переменные, объявленные в блоке инициализации, должны быть одного типа.

мы не можем инициализировать различные типы данных в цикле for в соответствии с их дизайном. Я просто привожу небольшой пример.

for(int i=0, b=0, c=0, d=0....;/*condition to be applied */;/*increment or other logic*/){
      //Your Code goes here
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.