在VBA中,我可以通过以下两种方式之一创建对象:
'First way
Dim myCol1 As New Collection
'Second way
Dim myCol2 As Collection
Set myCol2 = New Collection
myCol1.Add "AAA" 'Works
myCol2.Add "BBB" 'Works as well
第二种方式是第一种方式的更详细的版本,还是myCol1和myCol2对象之间实际上有区别?
答案 0 :(得分:14)
有几个关键的区别。你绝对应该选择第二种Dim/Set
方法。
原因1 - 使用As New
,在调用该对象的属性或方法之前,不会创建对象,但请查看此示例,其中将对象设置为Nothing,然后调用属性/方法会导致对象重新实例化:
Sub ShortcutInstantiation()
Dim x As New Collection
x.Add "FOO", "BAR"
Set x = Nothing
'This line implicitly recreates a new Collection
Debug.Print x.Count
Debug.Print x Is Nothing 'Prints False
End Sub
Sub SafeInstantiation()
Dim x As Collection
Set x = New Collection
x.Add "FOO", "BAR"
Set x = Nothing
'Throws error because x is nothing
Debug.Print x.Count
End Sub
原因2 As New
方法较慢,因为VBA需要在每个属性或方法调用之前检查它是否已实例化对象。
看看这个伪代码,看看VBA在幕后做了什么:
Sub NotSoShortcutInstantiation()
Dim x As New Collection
If x Is Nothing Then Set x = New Collection
x.Add "FOO", "BAR"
If x Is Nothing Then Set x = New Collection
x.Add "FIZZ", "BUZZ"
If x Is Nothing Then Set x = New Collection
x.Add "CAR", "DOOR"
If x Is Nothing Then Set x = New Collection
Debug.Print x.Count
End Sub
原因3 如果对象构造函数在之后执行某些操作,而不是在显式实例化它时,可能存在严重的时序差异:
比较此代码的结果:
Sub InstantiationTiming()
Dim foo As String
Dim x As New Class1
Debug.Print Format(Now(), "hh:mm:ss") & " x should be ready"
foo = x.foo
Dim y As Class1
Set y = New Class1
Debug.Print Format(Now(), "hh:mm:ss") & " y should be ready"
foo = y.foo
End Sub
As New
方法打印:
06:36:57 x should be ready
06:36:57 Class Initialized
Set y = New
方法打印:
06:36:57 Class Initialized
06:36:57 y should be ready
答案 1 :(得分:6)
Option Explicit
Private mdicQueryStringParams As New Scripting.Dictionary
Function SafeItem(ByVal sKey As String, ByRef pvItem As Variant) As Boolean
If mdicQueryStringParams.Exists(sKey) Then
pvItem = mdicQueryStringParams.Item(sKey)
SafeItem = True
End If
End Function
构造具有合法用途。在类中,如果您不知道将首先调用哪个方法,则使用模块级变量,然后它会保存一些代码行。因此,我在这里给出了一些代码片段
mdicQueryStringParams
想象一下,有很多方法依赖于初始化的Sub Class_Initialize
。您必须编写保护代码以确保它是在所有这些方法中创建的。
现在,您正在说,但是您可以在创建课程时使用New
到Private Sub Class_Initialize()
Set mdicQueryStringParams = New Scripting.Dictionary
End Sub
。喜欢这个
mdicQueryStringParams
但是假设我想要回收/重置该类状态的一部分,那么我可以编写一个将Nothing
设置为Sub Class_Initialise
的Clear方法。在这种情况下,Sub Class_Initialise
将不会再次运行。在这里SO Mat's Mug告诉我静态类在VBA中是可能的(谢谢!)所以有时候As New
只能运行一次。
(^不可否认,我可以在Clear方法中将其设置为新实例,是的,是的,我知道,我知道)
关键在于使用import numpy as np
X = np.loadtxt("i.txt",dtype=float)
birch_model = Birch(threshold=7.0, n_clusters=None)
birch_model.fit(X)
result = birch_model.predict(X)
语法获得复活变量以及自动初始化。当然,作为开发人员,这是我们工具箱中的另一种技术/模式,我们应该利用而不是禁止。
事实上,我很少使用它,但我只是不喜欢禁止的东西。