VB.NET:如果我将 String ByVal 传递给函数但不更改该字符串,那么内存中是否有一个或两个字符串?
我知道字符串是不可变的,因此一旦更改字符串引用的值,.NET 就会在堆上创建一个全新的字符串。
但是,如果您不更改字符串引用的值怎么办? 相反,您只需将其传递给函数 ByVal
——此操作是否也会复制堆上的字符串值? 我的倾向是“不”,但我想确认一下。
例如:
Public Function IsStringHello(ByVal test As String) As Boolean
Return (String.Compare(test, "Hello") = 0)
End Function
调用程序:
Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)
我知道按值传递 myWord
会复制“Blah”的引用,但由于我没有尝试更改字符串本身,因此它会在堆上制作另一个字符串副本吗?
I know strings are immutable, so the minute you change a string reference's value .NET makes a brand new string on the heap.
But what if you don't change the value of a string reference; rather, you simply pass it into a function ByVal
-- does this operation copy the string value on the heap as well? My inclination is "no," but I'd like to confirm.
For example:
Public Function IsStringHello(ByVal test As String) As Boolean
Return (String.Compare(test, "Hello") = 0)
End Function
Calling program:
Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)
I know passing myWord
by value makes a copy of the reference to "Blah", but since I have not tried to change the string itself, would it make another copy of the string on the heap?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
顺便说一句,字符串驻留与此完全无关。 对于所有引用类型(实际上是所有类型),将参数传递给函数的规则都是相同的,无论它们内部如何管理。
规则很简单,并且您已经正确表述了:按值传递会复制引用,而不是目标。 这里没有复制堆空间。
By the way, string interning is completely unrelated to that. The rule for passing parameters to functions is the same for all reference types (and really, all types), no matter how they are managed internally.
The rule is simple and you have stated it correctly: pass by value copies the reference, not the target. No heap space is copied here.
不,它仍然使用“Blah”的引用副本。
是什么让你认为它会发生?
附带说明一下,字符串是被拘留的。
和 两者都引用相同的字符串(因为它是内部的)。 如果修改 s 或 t,它将创建一个新字符串。
No. it still uses the copy of the reference to the "Blah".
What makes you think, it will?
On a side note, string are interned.
s & t both refer to the same string (because it is interned). If you modify s or t, it will create a new string, then.
传递对象 ByVal 会创建指针的副本,而不是对象本身。 这是一个演示:
该程序输出以下内容:
因此,原始字符串和我们按值传递的字符串存在于内存地址中的同一地址。 您没有复制字符串本身。
Passing objects ByVal creates a copy of the pointer, not the object itself. Here's a demonstration:
This program outputs the following:
So, the original string and the string we passed by value exist at the same address in memory address. You're not making a copy of the string itself.
很短,没有。 它将引用传递给字符串。 字符串本身只有一个实例。
Is short, no. It passes a ref to the string. Only one instance of the string itself.
字符串是引用类型。 如果按值传递,则传递的是引用的值。
在堆上获得另一个副本的唯一方法是更改变量的值。
string is a reference type. If you pass it by value, what you are passing is the value of the reference.
The only way you'd get another copy on the heap would be to change the variable's value.
System.String
类型的变量有效地保存一个“对象 ID”。 假设Object #1934
是一个包含字符"Blah"
的字符串,并且您说Dim myWord As String = "Blah"
。 然后,编译器会将Object #1934
存储到myWord
中。 调用IsStringHello(myWord)
将导致调用该函数,其test
参数等于Object #1934
。 在您的示例中,内存中有两个System.String
类型的变量 -myWord
和test
,并且两者都将保存内容 <代码>对象#1934。A variable of type
System.String
effectively holds an "object-ID". Suppose thatObject #1934
is a string with the characters"Blah"
, and you sayDim myWord As String = "Blah"
. The compiler will then storeObject #1934
intomyWord
. CallingIsStringHello(myWord)
would then cause that function to be called with itstest
parameter equal toObject #1934
. In your example, there would be two variables of typeSystem.String
in memory--myWord
andtest
, and both would hold the contentObject #1934
.