Область применения счетчика цикла for в Visual Basic

Рассмотрим следующее

Dim nofTries As Integer
For nofTires = 1 To 5
    If (condition) Then Exit For
Next 

Если из-за опечатки счетчик цикла отличается от объявленной переменной. Тем не менее, несмотря на настройку «явной опции», НЕТ предупреждения или ошибки компилятора, и это действовало так, как если бы:

Dim nofTries As Integer
For nofTires As Integer = 1 To 5
    If (condition) Then Exit For
Next 

Есть ли объяснение тому, почему компилятор взял на себя задачу принять тип вместо того, чтобы выдать ошибку?

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

Ken White 04.05.2024 01:35

Опция Explicit здесь не имеет значения. Начиная с .NET Framework 1.1, оператор For сам по себе считается объявлением, если указанная переменная еще не объявлена. Здесь уместен вариант Option Strict, потому что без вывода типа вам нужно будет указать тип данных объявляемой переменной. При выведении типа вам не требуется предложение As, если тип можно вывести из инициализирующего выражения. Поскольку 1 является целым числом, предполагается, что переменная имеет тип Integer.

jmcilhinney 04.05.2024 05:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это связано с включением OPTION INFER. Выключите его и появится нужная ошибка компилятора. Источником недоразумения для меня было то, что эта опция на самом деле не существует в VBA, но также и то, что она включена по умолчанию, тогда как отключение кажется более разумным.

Не только из-за включения Option Infer, но и из-за того, что в операторе For разрешено объявление переменной. Если бы у вас был nofTires = 1 где-то еще, это все равно было бы ошибкой необъявленной переменной, а не объявлением новой переменной с выведенным типом, как это происходит в цикле For.

GSerg 04.05.2024 01:04

Отключение Option Infer по умолчанию абсолютно неразумно. Вывод типа был введен специально для поддержки LINQ и требуется в определенных сценариях LINQ.

jmcilhinney 04.05.2024 05:45

Да, это неудачный результат сочетания Option Explicit с Option Infer.

Однако я считаю ошибкой читать из этого, что вам следует избегать Option Infer. Эта опция позволяет реализовать некоторые действительно приятные вещи в современном VB.Net, особенно (но не исключительно) в отношении Linq. В большинстве сценариев вам действительно нужно включить Option Infer (как и Explicit).

Традиционные циклы For — неудачный случай, потому что они позволяют вам использовать цикл для объявления переменной, удовлетворяющей Option Explicit, а затем Option Infer может позволить вам опустить определение типа, поэтому синтаксис выглядит как «просто используйте переменную», даже если вы набрали это неправильно... даже если при внимательном рассмотрении мы увидим, что переменная фактически объявлена, а также ей присвоен определенный тип посредством вывода.


Хитрость в том, что люди предпочитают меньше/более короткий код. Зачем печатать больше? Поэтому любой, кто работал с современным VB.Net в течение сколько-нибудь значимого периода времени, предпочтет идиоматически написать цикл без отдельной строки для определения переменной, например так:

For nofTires As Integer = 1 To 5
    If (condition) Then Exit For
Next 

Обратите внимание, что имя переменной по-прежнему неверно, но оно имеет значение только в том случае, если вы последовательно используете одно и то же имя (правильное или неправильное) внутри цикла. Если затем вы попытаетесь использовать «правильный» nofTries внутри этого цикла, код завершится ошибкой, поскольку переменная не была объявлена. Это даст программисту возможность исправить ситуацию. Таким образом, мы также видим, что дополнительная строка для объявления переменной — это не просто дополнительная типизация или личные предпочтения, но она также активно делает ваш код более хрупким.

Кроме того, пользователи современного идиоматического VB.Net, как правило, вообще имеют меньше традиционных циклов For, предпочитая вместо этого использовать операцию For Each или linq, а это означает, что эта проблема не возникает так часто, как вы думаете.


Мне интересно, можно ли получить предупреждение компилятора (или анализатора) (а не об ошибке) для кода, в котором переменная, определенная в цикле For, никогда не используется... но есть и законные практические причины сделать это, когда количество итерации - это то, что важно, и значение индекса каждой итерации не требуется.

Спасибо, это интересно, так как я ничего не знал о LINQ. Моей целью было узнать, сколько итераций выполнен цикл, и я был просто поражен, увидев, что счетчик всегда был равен нулю после выхода из цикла, пока я не заметил необычную опечатку. после этого я потратил почти час, пытаясь понять, почему явная опция не работает так, как я ожидал.

Ernesto 07.05.2024 04:58

Другие вопросы по теме