【问题标题】:Confusion over shallow copies of arrays in Visual Basic在 Visual Basic 中对数组的浅拷贝感到困惑
【发布时间】:2019-06-25 07:02:13
【问题描述】:

我的理解是数组的浅拷贝复制数组变量,这样你就有两个指针指向堆上的同一个内存位置。但是按照这个逻辑,下面这段代码应该可以工作,但不能:

Sub Main()
    Dim row As Long() = {1, 2, 3, 4}
    ChangeRow(row.Clone)
    Console.WriteLine(row(0))
End Sub

Sub ChangeRow(ByVal array As Long())
    array(0) = 0
End Sub

Clone 方法应该是做一个浅拷贝。这意味着您将指向原始数组的指针作为参数传递。到目前为止,我在该主题上阅读的所有内容都指向这段代码有效,但事实并非如此。谁能解释一下?

有问题的方言是 VB.Net

【问题讨论】:

  • 请说明这是什么方言,VB.NET、VB6、VBA等
  • 方言是VB.Net
  • 所以最重要的标签不见了……
  • @trincot 抱歉,这一天很长

标签: arrays vb.net parameters parameter-passing shallow-copy


【解决方案1】:

我的理解是数组的浅拷贝复制数组变量,这样你就有两个指针指向堆上的同一个内存位置。

没有。它创建了一个容器,包含所有相同的项目,其他方面与前一个容器相同,但容器本身位于堆上的不同位置。它不会创建对前一个容器的重复引用。

您所描述的只是一个参考。考虑这段代码:

Dim row As Long() = {1, 2, 3, 4}
Dim otherRow as Long() = row

程序的内存现在看起来有点像这样:

Clone 确实会创建一个浅拷贝——也就是说,它将创建一个 new 数组,其中包含与原始数组相同的所有值。然后,您在该新数组的第一项设置值,但这不会影响原始数组,因为它们是完全不同的数组,彼此之间没有运行时引用。考虑这段代码:

Dim row As Long() = {1, 2, 3, 4}
Dim otherRow as Long() = row.Clone

程序的内存现在看起来有点像这样:

如果您想在ChangeRow 子例程中修改原始数组,请不要调用clone。

Sub Main()
    Dim row As Long() = {1, 2, 3, 4}
    ChangeRow(row)
    Console.WriteLine(row(0)) ' outputs 0
End Sub

Sub ChangeRow(ByVal array As Long())
    array(0) = 0
End Sub

为了说明为什么这实际上是一个“浅”副本,请检查它如何与引用类型一起使用。

Class Ref
    Public Value As Long 
    Public Sub New(ByVal value As Long)
        Value = value
    End Sub
End Class

Sub Main()
    Dim row As Ref() = {New Ref(1), New Ref(2), New Ref(3), New Ref(4)}
    ChangeRow(row.Clone)
    Console.WriteLine(row(0).Value) ' outputs 0
End Sub

Sub ChangeRow(ByVal array As Ref())
    array(0).Value = 0
End Sub

尽管rowrow.Clone 引用了不同的数组,但这些数组(Ref 的实例)中的值是相同的,因此修改array(0).Value 与修改row(0).Value 相同。在这种情况下,程序的内存看起来有点像这样:

【讨论】:

  • 是不是意味着只要数组中包含的值本身不是引用类型,克隆会创建独立的副本,而深度复制会创建一个独立的数据集,不管数据是否包含数组中是否为引用类型?
  • 是的。一般而言,术语“浅拷贝”是指仅将存储器结构复制到仅一层深度,而术语“深拷贝”是指将存储器结构复制到任意深度。如果你的数组只包含值类型,那么是的,结构只会下降一层——你不能再深入了。
  • 感谢您澄清这一点。课程材料在这个主题上非常模糊和无益。
  • @VisualVincent 我想这是来自一个叫 Visual Vincent 的人的高度赞扬。它实际上只是 MS Paint。 :)
  • 尽管您不需要成为艺术家或使用昂贵的程序来完成出色的工作!在这种情况下,重要的是你如何传递“信息”,我很惊讶你能完美地做到这一点!每个人都可以画一幅画,但不是每个人都可以用这么少的内容来画出如此丰富的内容!
猜你喜欢
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2011-08-01
  • 2012-01-29
相关资源
最近更新 更多