JSLint неожиданно сообщает: используйте форму функции & ldquo; используйте строгий & rdquo;

Позвольте мне сказать это очень четко, потому что люди все время неправильно понимают это:

Порядок оценки подвыражений является независимым как ассоциативности, так и приоритета. Ассоциативность и приоритет определяют, в каком порядке выполняются операторы , но не определяют, в каком порядке оцениваются подвыражения . Ваш вопрос касается порядка, в котором оцениваются подвыражения .

Рассмотрим A() + B() + C() * D(). Умножение имеет более высокий приоритет, чем добавление, а добавление лево-ассоциативное, поэтому это эквивалентно (A() + B()) + (C() * D()). Но зная, что только говорит вам, что первое добавление произойдет до второго добавления и что умножение произойдет до второго добавления. Он не говорит вам, в каком порядке будем называть A (), B (), C () и D ()! (Он также не говорит вам, происходит ли умножение до или после первого добавления.) Было бы вполне возможно подчиняться правилам приоритета и ассоциативности , компилируя это как:

d = D()          // these four computations can happen in any order
b = B()
c = C()
a = A()
sum = a + b      // these two computations can happen in any order
product = c * d
result = sum + product // this has to happen last

Все правила приоритета и ассоциативности следуют туда - первое дополнение происходит до второго добавления, а умножение происходит до второго добавления. Ясно, что мы можем выполнять вызовы A (), B (), C () и D () в любом порядке и по-прежнему подчиняться правилам приоритетности и ассоциативности!

Мы требуется правило , не связанное с правилами приоритета и ассоциативности, чтобы объяснить порядок, в котором оцениваются подвыражения. Соответствующим правилом в Java (и C #) является «подвыражения оцениваются слева направо». Так как A () появляется слева от C (), сначала оценивается A (), независимо от того, что C () участвует в умножении, а A () участвует только в добавлении.

Итак, теперь у вас достаточно информации, чтобы ответить на ваш вопрос. В a[b] = b = 0 правила ассоциативности говорят, что это a[b] = (b = 0);, но это не значит, что b=0 работает первым! В правилах приоритета говорят, что индексирование имеет более высокий приоритет, чем присвоение, но это не означает, что индексатор работает до самого правого присваивания.

Правила приоритета и ассоциативности налагают ограничения, которые:

  • Операция индексатора должна выполняться до операции, связанной с операцией левого присваивания
  • Операция, связанная с операцией правого присваивания, должна выполняться до того, что связано с левым назначением .

Приоритет и ассоциативность говорят только о том, что присвоение нулю до b должно происходить до присвоения a[b] , Приоритет и ассоциативность ничего не говорят о том, оценивается ли a[b] до или после b=0.

Опять же, это то же самое, что: A()[B()] = C() - Все, что мы знаем, это то, что индексирование должно произойти до назначения. Мы не знаем, выполняется ли сначала A (), B () или C () на основе приоритета и ассоциативности . Нам нужно другое правило, чтобы сказать нам это.

Правило опять же «когда у вас есть выбор, что делать сначала, всегда идите влево-вправо»: a[b] находится слева от b=0, поэтому a[b] сначала запускает , в результате получается a[1]. Затем происходит b=0, а затем присваивание значения a[1] происходит последним.

Вещи слева случаются перед вещами справа. Это правило, которое вы ищете. Разговоры о приоритетности и ассоциативности оба сбивают с толку и неактуальны.

Люди все время ошибаются , даже люди, которые должны знать лучше. Я отредактировал слишком много книг по программированию, которые неправильно указали правила, поэтому неудивительно, что многие люди имеют совершенно неверные убеждения относительно взаимосвязи между приоритетом / ассоциативностью и порядком оценки, а именно, что в действительности нет таких отношений; они независимы.

Если эта тема вас интересует, см. мои статьи по этому вопросу для дальнейшего чтения:

http://blogs.msdn.com/b/ericlippert / archive / tags / priority /

Они относятся к C #, но большая часть этого материала одинаково хорошо применима к Java.

904
задан Vikrant 21 December 2016 в 11:09
поделиться