Я использую ключевое слово Call
при вызове subs в VB/VBA. Я знаю, что это необязательно, но лучше ли использовать его или оставить его? Я всегда думал, что это было более явным, но, возможно, это просто шум.
Кроме того, я читаю это на другом форуме: использование ключевого слова Call
выполняется быстрее, потому что он знает, что он не будет возвращать какие-либо значения, поэтому ему не нужно настраивать любое стековое пространство, чтобы освободить место для возврата значение.
Ага. Я давно задумывался об этом, и даже чтение двухдюймовой книги на VBA в основном говорит, что не используйте его, если вы не хотите использовать функцию Найти VBE, чтобы легко находить вызовы в больших проектах.
Но я просто нашел другое применение.
Мы знаем, что возможно объединить строки кода с символом двоеточия, например:
Function Test(mode as Boolean)
if mode = True then x = x + 1 : Exit Sub
y = y - 1
End Sub
Но если вы делаете это с вызовами процедур в начале строки, VBE предполагает, что вы ссылаетесь на метку и удаляет любые отступы, выравнивая строку до левого поля (даже если процедура вызывается как предполагаемая ):
Function Test()
Function1 : Function2
End Function
Использование оператора Вызов позволяет конкатенацию вызовов процедур при сохранении отступов кода:
Function Test()
Call Function1 : Call Function2
End Function
Если вы не используете оператор Вызов в приведенном выше примере, VBE предположит, что "Function1" - это метка и выровнять по левому краю в окне кода, даже если он не будет вызывают ошибку.
Для VB6, если есть вероятность, что он будет преобразован в VB.NET, использование Call
означает, что синтаксис не изменяется. (Скобки в VB.NET требуются для вызовов методов.) (Я лично не считаю, что это стоит того, что любой конвертер .NET, по крайней мере, сможет поместить в круглые скобки, когда это необходимо. Я просто перечисляю его как причина.)
В противном случае это просто синтаксический сахар.
Обратите внимание, что ключевое слово Call
, скорее всего, не будет быстрее при вызове какого-либо другого метода/функции, потому что функция все равно возвращает свое значение, а VB не нужно создавать локальную переменную для ее получения, даже если Call
не используется.
Я всегда использую Call
в VBA. Для меня это выглядит просто чище. Но, я согласен, это просто синтаксический сахар, который ставит его прямо в сферу личных предпочтений. За последние несколько лет я встретил, вероятно, дюжину парней VBA, и ни один из них не использовал Call
. Это имело дополнительное преимущество, что я всегда знал, какой код был моим.: Р
Нет, он просто добавит 7 символов за вызов без какой-либо выгоды.
Если вы читаете страницу поддержки MSDN для Statement Statement, для конкретного случая o VBA, по крайней мере, он говорит, что Вызов не является обязательным, но что очень важно, и никто, кажется, не заметил, это цитата:
"Если вы используете синтаксис Call для вызова любой внутренней или пользовательской функции, возвращаемое значение функции отбрасывается."
Вот почему Вызов далеко не бесполезен. Предположим, вы пишете Sub SupportTasks, который делает для вас очень важные материалы для основного раздела (например, он импортирует данные из файла, который будет использоваться различными процедурами). Теперь обратите внимание, что, поскольку SupportTasks читает внешние данные, всегда есть вероятность, что эти данные не будут стандартными, а суб не сможет выполнять свою роль. Что вы делаете?
Вы можете, например, использовать логические функции, которые возвращают False, если что-то пойдет не так. Вместо вызова sub вызовите функцию SupportTasks внутри и If, которая выйдет из Main sub, если есть аномалия:
If Not SupportTasks(SomeArgument) Then
Application.ScreenUpdating = True
Exit Sub
'Else continue the Main sub regularly without writing anything in here
End If
Если вам интересно, как это связано с Вызов, рассмотрите следующее: в другом подпроцессе я вызываю SupportTasks, но мне не нужно его возвращаемое логическое значение (например, Я уверен, что ошибка не произойдет). Ну, если я не помещаю его в оператор If или не назначаю функцию бесполезной переменной, VBA не будет компилировать и не возвращать мне ошибку (вызов процедуры недействителен бла-бла-бла должен присваивать значение чему-то бла-бла-бла). Что там, где Вызов входит, чтобы сохранить день!
Call SupportTasks(SomeArgument) '<< "Call Function" call doesn't return an error
Если вы все еще считаете это бесполезным, подумайте об этом как о ресурсе, чтобы оставаться организованным. Написание отдельных процедур для подпрограмм, разделяемых многими процедурами, делает ваш код короче и более понятным, особенно когда вы пишете действительно большие приложения. Например, ERP, построенный на основе интеграции Excel-Access, может быть проще в эксплуатации, ремонте и настройке, если ваш ИТ-отдел медленно доставляет/реализует реальную систему...
В заключение, некоторые интернет-мудрости:
Всегда пишите свой код, как если бы человек, который его рассмотрит, является убийственным психопатом, который знает, где вы живете.
Аминь.
SupportTasks SomeArgument
и он прекрасно компилируется без использования Call
.
Я использую Call
для всех VBA-разработок общих функций библиотеки, которые я, возможно, буду использовать в VB.NET. Это позволяет мне перемещать код с помощью копирования и вставки между всеми вкусами VB. Я делаю это, чтобы избежать ошибок синтаксиса, создаваемых редактором кода, когда он "форматирует" или "красиво печатает" вставленный код. Единственными изменениями обычно являются включение/исключение оператора Set
.
Если вы не планируете переводить код VB/VBA на VB.NET, тогда нет необходимости использовать оператор Call
.
Единственный случай, когда я нашел "вызов", полезен - это случайность, касающаяся некоторых специальных операторов.
Dim c As IAsyncOperation(Of StartupTask) = StartupTask.GetAsync("Startup")
……
(Await c).Disable()
Я получил синтаксическую ошибку для второй строки, точно так же, как вы получите с оператором "New". Я действительно не хочу новую переменную, которая слишком не элегантна для меня. Итак, я попробовал:
DirectCast(Await c, StartupTask).Disable()
Это синтаксически правильно. Но затем IDE намекнул, что "DirectCast" не нужен, и дал упрощение. Да, это:
Call (Await c).Disable()
Вот почему я люблю VS2017 Preview.
Я опаздываю на вечеринку на 7 лет, но я просто случайно встретил ключевое слово Call
несколько минут назад, читая что-то в MSDN. В частности, он использовался для выполнения чего-то, что, как я думал, невозможно в VB.NET(в отличие от С#), что связано с ответом @FCastro.
Class Test
Public Sub DoSomething()
Console.WriteLine("doing something")
End Sub
End Class
Sub Main()
Call (New Test()).DoSomething()
End Sub
В нечетном случае вам не нужен фактический экземпляр объекта, но требуется один из его методов, вы можете использовать Call
для сохранения строки. Обратите внимание, что это необязательно, если это правая часть операции:
Class Test
Public Function GetSomething() As Integer
Return 0
End Function
End Class
Sub Main()
Dim x As Integer = (New Test()).GetSomething()
End Sub
Старый поток, но я не вижу, чтобы кто-то охватывал это важное различие: в некоторых (распространенных) ситуациях Call не позволяет скобкам вокруг аргументов функции (и под) вызывать строгую интерпретацию аргументов как ByVal.
Большой вывод для вас заключается в том, что если вы действительно используете круглые скобки вокруг аргументов процедуры, возможно, наизусть или по привычке, даже если они не требуются, то вы ДОЛЖНЫ ИСПОЛЬЗОВАТЬ Call, чтобы гарантировать, что подпрограмма неявного или явного ByRef не будет проигнорирована в пользу ByVal; или, вместо этого, вы должны использовать присваивание "знака равенства" возвращаемого значения для предотвращения игнорирования (в этом случае вы не будете использовать Call).
Опять же, это должно защитить вас от неблагоприятного получения ByVal от рутины. И наоборот, если, конечно, вы ХОТИТЕ интерпретацию ByVal независимо от объявления процедуры, тогда ВЫКЛЮЧИТЕ вызов (и используйте скобки).
Обоснование: обобщение https://msdn.microsoft.com/en-us/library/ee478101%28v=vs.84%29.aspx "Параметры ByRef и ByVal"
Если
1. есть назначение возврата вызова функции, например
iSum = myfunc (myArg)
или же
2. "Call" используется, например,
позвоните myFunc (myArg)
или же
позвоните mySub (myArg)
тогда круглые скобки строго разграничивают список вызывающих аргументов; объявление процедуры определяет ByVal или ByRef. В противном случае скобки заставляют ByVal использоваться подпрограммой - хотя ByVal не был указан в подпрограмме. Таким образом,
mySub (myArg) 'использует ByVal независимо от объявления процедуры
в то время как
Вызов mySub (myArg) использует ByRef, если подпрограмма не объявляет ByVal
Также обратите внимание, что Call синтаксически требует использования скобок. Вы можете пойти
mySub myArg
но ты не можешь идти
позвоните mySub myArg
но вы можете пойти
позвоните mySub (myArg)
(и синтаксически необходимы скобки для присвоения возвращаемого значения функции)
ВНИМАНИЕ, однако, что ByVal в объявлении процедуры отменяет все это. И к вашему сведению, ByRef всегда подразумевается в декларации, если вы молчите; Таким образом, TMK ByRef не имеет очевидного значения, кроме документального.
Повторение сверху: большой вывод для вас заключается в том, что если вы действительно используете круглые скобки вокруг аргументов процедуры, возможно, наизусть или по привычке, даже если они не требуются, тогда вы ДОЛЖНЫ ИСПОЛЬЗОВАТЬ Call, чтобы гарантировать, что подпрограмма неявного или явного ByRef будет не игнорируется в пользу ByVal; или, вместо этого, вы должны использовать присваивание "знака равенства" возвращаемого значения для предотвращения игнорирования (в этом случае вы не будете использовать Call).
Опять же, это должно защитить вас от неблагоприятного получения ByVal от рутины. И наоборот, если, конечно, вы ХОТИТЕ интерпретацию ByVal независимо от объявления процедуры, тогда ВЫКЛЮЧИТЕ вызов (и используйте скобки).
Call New RNGCryptoServiceProvider().GetBytes(salt)
безCall
Я бы сначала использовал переменнуюRNGCryptoServiceProvider