В VB (A) есть идеальная логика для правила круглых скобок, и оно выглядит следующим образом.
Если процедура (функция или подпрограмма) вызывается с аргументами, и вызов находится в строке сдругие утверждения или ключевые слова, аргументы должны быть заключены в скобки.Это позволяет отличить аргументы, относящиеся к вызову процедуры, от остальной части строки.Итак:
1: If CheckConditions(A, B, C) = DONT_PROCEED Then Exit Sub
- допустимая строка;вызов CheckConditions нуждается в скобках, чтобы указать, какие другие биты строки являются его аргументами.И наоборот, это приведет к синтаксической ошибке:
2: If CheckConditions A, B, C = DONT_PROCEED Then Exit Sub
Поскольку невозможно выполнить синтаксический анализ.
Если в качестве единственного оператора в строке используется вызов процедуры, скобки не нужны, посколькуЯсно, что аргументы относятся к вызову процедуры:
3: SaveNewValues Value1, Value2, Value3
Хотя это приводит к синтаксической ошибке (по разумным причинам, обсуждаемым ниже):
4: SaveNewValues(Value1, Value2, Value3)
Чтобы избежать путаницы в скобках илибез скобок (фактически, чтобы полностью исключить правило скобок), всегда полезно использовать ключевое слово Call для таких вызовов;это гарантирует, что вызов процедуры не является единственным оператором в строке, поэтому требуются круглые скобки:
5: Call SaveNewValues(Value1, Value2, Value3)
Так что, если вы привыкли предшествовать вызовам отдельных процедур с ключевым словом Call, вы можете забытьправило круглых скобок, потому что тогда вы всегда можете заключить свои аргументы в круглые скобки.
Дело в том, что скобки играют дополнительную роль в VB (A) (и во многих других языках): они также указывают приоритет оценки для выражений,Если вы используете круглые скобки в любом другом контексте, кроме как для того, чтобы заключить аргументы вызова процедуры, VB (A) будет пытаться вычислить выражение в круглых скобках до получающегося простого значения.
Таким образом, в примере 4, где круглые скобки недопустимыдля включения аргументов VB (A) вместо этого попытается вычислить выражение в скобках.Поскольку (Value1, Value 2, Value3) не является выражением, которое может быть оценено, возникает синтаксическая ошибка.
Это также объясняет, почему вызовы с переменной, переданной ByRef, действуют так, как если бы они вызывались ByVal, если аргумент заключен вскобки.В приведенном выше примере, где функция p вызывается с параметром ByRef a, существует большая разница между этими двумя вызовами p:
6: p a
И
7: p(a)
Как обсуждалось выше,6 - правильный синтаксис: вызов в своей строке один, поэтому не следует использовать круглые скобки для заключения аргументов.
В 7 аргумент в любом случае заключен в круглые скобки, предлагая VB (A) оценитьвложенное выражение в простое значение.Что, конечно, само определение прохождения ByVal.Скобки гарантируют, что вместо указателя на a передается значение a, а a остается неизменным.
Это также объясняет, почему правило круглых скобок не всегда поддерживается.Самым ярким примером является вызов MsgBox:
8: MsgBox "Hello World!"
и
9: MsgBox ("Hello World!")
Оба они верны, хотя правило скобок указывает, что 9 должно быть неверным.Это, конечно, но все, что происходит, это то, что VB (A) оценивает выражение в скобках.И строковый литерал вычисляется до точно такого же строкового литерала, так что фактический сделанный вызов равен 8. Другими словами: вызовы процедур с одним аргументом с постоянными или строковыми литеральными аргументами имеют одинаковый результат с круглыми скобками или без них.(Вот почему даже моим вызовам MsgBox предшествует ключевое слово Call.)
Наконец, это объясняет странные ошибки несоответствия типов и странное поведение при передаче аргументов объекта.Допустим, в вашем приложении есть процедура HighlightContent, которая принимает в качестве аргумента TextBox (и, вы никогда не догадаетесь, выделяет его содержимое).Вы вызываете это, чтобы выделить весь текст в текстовом поле.Вы можете вызвать эту процедуру тремя синтаксически правильными способами:
10: HighlightContent txtName
11: HighlightContent (txtName)
12: Call HighlightContent(txtName)
Допустим, ваш пользователь ввел «Джон» в текстовое поле, а ваше приложение вызывает HighlightContent.Что будет, какой звонок сработает?
10 и 12 верны; имя Джон будет выделено в текстовом поле. Но 11 синтаксически правильно, но приведет к ошибке компиляции или времени выполнения. Зачем? Потому что скобки неуместны. Это побудит VB (A) попытаться оценить выражение в скобках. И результатом оценки объекта чаще всего будет значение его свойства по умолчанию; .Текст в этом случае. Таким образом, вызов процедуры, подобной 11, не передаст объект TextBox процедуре, а приведет к строковому значению "John" В результате несоответствие типов.