Разница между ByVal и ByRef? - PullRequest
       66

Разница между ByVal и ByRef?

18 голосов
/ 05 февраля 2011

В чем разница?Я всегда использую ByVal, но я не очень понимаю, когда мне следует, а когда нет ...

Ответы [ 9 ]

11 голосов
/ 09 марта 2011

ByRef = Вы даете своему другу курсовую работу (оригинал), он помечает ее и может вернуть вам.

ByVal = Вы даете ему копию курсовой работы, и он возвращает вам свои изменения, но вы должны сами вернуть их в свой оригинал.

Так просто, как я могу это сделать.

Зачем использовать Byref:
ByRef передаст указатель на объект, который вы передаете. Если вы находитесь в одном и том же пространстве памяти, это означает передачу только «слова», а не объекта. Метод, которому вы передаете его, может вносить изменения в исходный объект, и ему вообще не нужно передавать их обратно, как они есть в исходном объекте. Полезно для ускорения передачи больших данных. Вы также можете использовать ByRef, чтобы разрешить использование SUB, а не FUNCTION (в VB), поскольку ему не нужно возвращать объект.

Почему бы не использовать Byref:
Поскольку метод имеет доступ к оригиналу, любые сделанные изменения будут немедленными и постоянными. В случае сбоя метода объект может быть поврежден. Использование ByVal создаст копию, передаст всю копию в метод, а затем метод обработает информацию и либо повторно вернет копию, сообщит информацию или ничего не сделает.

10 голосов
/ 05 февраля 2011

Если вы передадите ссылку, то при изменении значения в методе переменная на сайте вызова также будет изменена.

Если вы передадите значение, оно будет таким же, как если бы в методе была создана другая переменная, поэтому даже если вы измените его, исходная переменная (на сайте вызова) не изменит свое значение.

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

5 голосов
/ 19 апреля 2011

Я знаю, что на этот вопрос довольно много ответов, но я просто хотел добавить следующее ...

Однако объект, который вы передаете функции, подчиняется ByRef / ByVal, если этот объект содержитссылки на другие объекты, они могут быть изменены вызываемым методом независимо от ByRef / ByVal.Плохое объяснение, я знаю, см. Код ниже для лучшего понимания:

Public Sub Test()
    Dim testCase As List(Of String) = GetNewList()
    ByRefChange1(testCase)
    'testCase = Nothing
    testCase = GetNewList()

    ByValChange1(testCase)
    'testCase is unchanged
    testCase = GetNewList()

    ByRefChange2(testCase)
    'testCase contains the element "ByRef Change 2"
    testCase = GetNewList()

    ByValChange2(testCase)
    'testCase contains the element "ByVal Change 2"

End Sub

Public Function GetNewList() As List(Of String)
    Dim result As List(Of String) = New List(Of String)
    result.Add("Value A")
    result.Add("Value B")
    result.Add("Value C")
    Return result
End Function

Public Sub ByRefChange1(ByRef aList As List(Of String))
    aList = Nothing
End Sub

Public Sub ByValChange1(ByVal aList As List(Of String))
    aList = Nothing
End Sub

Public Sub ByRefChange2(ByRef aList As List(Of String))
    aList.Add("ByRef Change 2")
End Sub

Public Sub ByValChange2(ByVal aList As List(Of String))
    aList.Add("ByVal Change 2")
End Sub

РЕДАКТИРОВАТЬ:

Также, подумайте, если эта функция была вызвана:

Public Sub ByValChange3(ByVal aList As List(Of String))
    aList.Add("ByVal Change 3")
    aList = New List(Of String)
    aList.Add("ByVal Change 4")
End Sub

Чтопроисходит в этом случае, если «ByVal Change 3» добавляется в список вызывающих, но в тот момент, когда вы указываете, что «aList = New List», вы затем указываете новую ссылку на новый объект и отсоединяетесь от списка вызывающих,И здравый смысл, и может настигнет вас однажды, так что стоит иметь в виду.

5 голосов
/ 05 февраля 2011

ByRef похож на второе возвращаемое значение. Он передает ссылку на объект в функцию, а не сам объект. Если вы измените значение параметра ByRef в функции, вы увидите эти изменения после завершения функции. Если это было недостаточно ясно, прочитайте это и это .

0 голосов
/ 13 июня 2019

Я постараюсь объяснить разницу простыми словами.

  • передача аргумента по значению делает его входным параметром. Это самый безопасный способ, поэтому он используется по умолчанию в 95% случаев.

  • Передача аргумента по ссылке делает его входным и выходным параметром. Выходной параметр можно изменить внутри функции, которая создает редко используемый побочный эффект.

0 голосов
/ 05 апреля 2018

Ответы @Tom и @kelloti полезны. Вот пример кода, чтобы проиллюстрировать далее:

Private Function ValMessage(ByVal SomeMessage As String)
    SomeMessage = "Val Val Val" ' <-- this variable modification doesn't persist after the function finishes execution
    ValMessage = "Some Return Value"
End Function

Private Function RefMessage(ByRef SomeMessage As String)
    SomeMessage = "Ref Ref Ref" ' <-- this variable modification persists even after the function finishes execution
    RefMessage = "Some Return Value"
End Function

Private Sub DoStuff()
    Dim OriginalMessage As String
    Dim OtherMessage As String
    Dim AnotherMessage As String

    OriginalMessage = "Original"
    MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Original"

    OtherMessage = ValMessage(OriginalMessage)
    MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Original"

    AnotherMessage = RefMessage(OriginalMessage)
    MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Ref Ref Ref" <--- this is the difference when you pass a paramter by reference
End Sub
0 голосов
/ 23 апреля 2017

ByRef, одно значение будет иметь 2 адреса

Таким образом, если x = 80 (80 - это значение, а x - это адрес, то, например, переменная y также может быть 80, и, таким образом, к 80 можно обращаться по x и y)

0 голосов
/ 13 декабря 2016

Думаю, в последнем примере могла быть опечатка: Последний саб должен быть "byval", а не "byref". :)

Также добавлен оператор msgbox в try_byval, чтобы вы могли понять, что имеется в виду.

Sub begin()
Dim last_column As Integer

last_column = 234
MsgBox "Begin:" & last_column

trying_byref x:=last_column
MsgBox "byref:" & last_column

trying_byval v:=last_column
MsgBox "byval:" & last_column
End Sub

Sub trying_byref(ByRef x)
x = 111
End Sub

Sub trying_byval(ByVal v)  '<--not ByRef, that was in sub trying_byref.
v = 222
MsgBox "In Here:" & v
End Sub
0 голосов
/ 30 октября 2015

Я надеюсь, что это отвечает на ваш вопрос

Sub last_column_process()
Dim last_column As Integer

last_column = 234
MsgBox last_column

trying_byref x:=last_column
MsgBox last_column

trying_byval v:=last_column
MsgBox last_column

End Sub

Sub trying_byref(ByRef x)
x = 345
End Sub

Sub trying_byval(ByRef v)
v = 555
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...