我知道.NET(以及VB.NET)字符串是不可变的。但是,我在Excel 2010中使用VBA 7.0。字符串是否不可变?我正在进行大量的字符串处理,对于少量,一些(直接)字符串操作很好,但我担心它不会扩展 - 因为每个额外的字符从一个字符串移动到另一个字符串可能会创建另一个实例字符串。
答案 0 :(得分:8)
它们是不可变的,除非它们表现出可变行为,否则它们不是。
例如,通过mid$()
分配比正常的新字符串分配要快得多。
Dim s As String
s = "ABC"
Debug.Print s, StrPtr(s)
'// -> ABC 122899836
Mid$(s, 1, 1) = "Z"
Debug.Print s, StrPtr(s)
'// -> ZBC 122899836
s = "??" & Right$(s, 1)
Debug.Print s, StrPtr(s)
'// -> ??C 196635748
答案 1 :(得分:4)
VBA字符串是不可变的。
与VB.NET一样,没有创建新字符串就无法“替换部分”或“追加”字符串。这是否重要 - 因为现代计算机非常快 - 取决于实际的算法,数据和环境。
与.NET文档不同,VBA的这种行为参考[变得]难以追踪。从MS-VBAL: 2.1 Data Values and Value Types,我们发现这个罕见的小宝石
单个数据值是不可变的。这意味着VBA环境中没有可用的定义机制可以导致数据值更改为另一个数据值。
其中字符串表示“单个数据值”。
答案 2 :(得分:0)
VBA字符串是可变的。 Alex K的回答是错误的,但他对Microsoft VB.Net中的Mid()=
忽悠是正确的,尽管支持Mid()=
,但微软正确地声称它们是不可变的https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/strings/string-basics。
因此,在所有VB6,VBA,VB.Net中,您都可以使用如Alex答复中所述的Mid(a$, 1, 2)="hi"
来覆盖字符串的一部分。但是,正如user2864740所指出的那样,只有VB6和VBA才能极其迅速地完成此操作。这是VB6(VBA)和VB.Net中经过测试的代码。
Dim n1&, start!, bigstring$
bigstring$ = Space(10 ^ 6)
start = timer() ' in vb.Net this is function with "timer = (DateTime.Now.Ticks - Today.Ticks) / 10000000.0#"
For n1 = 1 To 5000
Mid(bigstring, n1, 1) = "1"
Next
Debug.Print("Elapsed millisecs: " & (timer() - start!) * 1000.0! & " over cycle count of " & n1 - 1)
在兆字节以上的大字符串上,此技术对于速度至关重要,因此可以扩展。在VBA上,它可以在一毫秒内完成此操作。但是,在VB.Net中,效率极低-在3GHz CPU上,此测试耗时7秒,每次迭代大约需要1ms。随着迭代次数从5000次增加到100万次,VBA仍然只需要40毫秒。 VB.Net将需要30分钟。提示:在VB.Net中,可以先使用Dim BigByte() as byte
然后使用BigByte = System.Text.Encoding.UTF8.GetBytes(bigstring)
,以便使用字节数组。如何使这种灵活性和Unicode超出了本主题。