Java: Ініціалізувати кілька змінних у циклі for init?


91

Я хочу мати дві змінні циклу різних типів. Чи є спосіб зробити так, щоб це працювало?

@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? Це ніде не оголошено. Це учасник класу?
екстранеон

7
Ви повинні прийняти одну відповідь нижче
Mr_and_Mrs_D

І на відміну від C, Java не має оператора коми: stackoverflow.com/questions/12601596/… , що дозволило б ініціалізувати (але не оголошувати) дві змінні різних типів.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

@ Нік Хайнер Не могли б ви позначити одну з наведених нижче відповідей як прийняту?
Джеймс Монгер

Відповіді:


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 - це найкраще поставити як окреме питання.
Макдауелл,

2
@JeffAxelrod, можливо з історичних причин, тому що Java була змодельована за C ++ ... див. Цю публікацію: stackoverflow.com/questions/2687392/…
Крістоф Руссі

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 - це нормально, оскільки перше використання - встановити його на first.
Джей,

Зазвичай для кращого збільшення приросту в циклі 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.