我正在阅读VBA-JSON的源代码,该代码位于:
https://github.com/VBA-tools/VBA-JSON/blob/master/JsonConverter.bas
在将JSON对象(以" {" char开头)转储到内存的函数中:
starttime = datetime.strptime(' '.join([now.year, e[4], e[0], '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')
endtime = datetime.strptime(' '.join([now.year, e[4], e[1]]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')
global epg_data
epg_data = u"""\
<programme start="{starttime} +0100" stop="{endtime} +0100" channel="{channel}">
<title lang="eng">{e5}</title>
<desc lang="eng">{e2} {e3}</desc>
<icon src="{div_list2}" />
<country>UK</country>
</programme>""".format(channel=escape(channel), starttime=starttime,
endtime=endtime,e5=escape(e5), e2=escape(e2), e3=escape(e3),
div_list2=escape(div_list2))
有什么区别:
Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Dictionary
Dim json_Key As String
Dim json_NextChar As String
Set json_ParseObject = New Dictionary
json_SkipSpaces json_String, json_Index
If VBA.Mid$(json_String, json_Index, 1) <> "{" Then
Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(json_String, json_Index, "Expecting '{'")
Else
json_Index = json_Index + 1
Do
json_SkipSpaces json_String, json_Index
If VBA.Mid$(json_String, json_Index, 1) = "}" Then
json_Index = json_Index + 1
Exit Function
ElseIf VBA.Mid$(json_String, json_Index, 1) = "," Then
json_Index = json_Index + 1
json_SkipSpaces json_String, json_Index
End If
json_Key = json_ParseKey(json_String, json_Index)
json_NextChar = json_Peek(json_String, json_Index)
If json_NextChar = "[" Or json_NextChar = "{" Then
Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
Else
json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
End If
Loop
End If
End Function
以下一个:
Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
我搜索了SO并找到了这篇文章,这并没有消除这种混淆:
What does the keyword Set actually do in VBA?
通过阅读代码,我理解如果解析器读取&#34; {&#34;或者&#34; [&#34;然后它需要使用一个字典来保存&#34; {&#34;和&#34;}&#34;,以及在#34; [&#34;和&#34;]&#34;,如果解析器读取的不是那两个,那么它只是一个值,可以是布尔值或字符串或整数等。
我不能得到的是Set和Assignment之间的区别。 &#34;设置&#34;将复制json_ParseValue的返回变量的地址,并且赋值只是生成返回变量的另一个副本。是因为在第一种情况下,还需要修改返回的对象,因此必须通过地址传递(就像我们使用的C ++中那样)?
答案 0 :(得分:3)
正如链接的Q&amp; A所说,Set
在VBA中用于分配对象引用。 Let
关键字可用于分配值,但Let
关键字几乎已过时/冗余。
这就是为什么你在属性mutator定义中有这些关键字的原因:
Private mSomething As Variant
Public Property Let Something(ByVal value As Variant)
mSomething = value ' value is a primitive
End Property
Public Property Set Something(ByVal value As Variant)
Set mSomething = value ' value is an object reference
End Property
到目前为止,这么好。这个区别:
Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
而且:
json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
这是因为json_ParseValue
返回的Variant
可以容纳任何内容,包括对象引用或简单值,那么在分配引用时需要使用Set
关键字,并离开在分配值时输出(或使用Let
关键字)。
如果不查看实施细节并确切了解返回的内容,就无法判断,但Let
分配可能会分配给默认成员 - 而且默认的成员调用是隐式的,确实让人感到困惑。
与您在Excel VBA中分配单元格值完全相同:
Dim r As Range
Set r = ActiveSheet.Range("A1")
VS
Dim r As Double
r = ActiveSheet.Range("A1") 'implicit call to ActiveSheet.Range("A1").[_Default]
这两个说明看起来只是因为一个有Set
个关键字而另一个没有,但真正的不同之处在于隐式成员对隐藏的成员调用名为[_Default]
的属性,具有VB_UserMemId = 0
属性,该属性使该成员成为类&#39; 默认会员。
混淆源于隐式默认成员调用,它使代码说某些东西,实际上做其他东西。
Rubberduck(我管理的OSS VBIDE加载项项目)有一个代码检查,用于在早期绑定代码中查找隐式默认成员分配:
隐式默认会员分配
这样的赋值看起来像是将对象变量赋值给表面上的值类型,但它们实际上是隐式地分配该对象的默认成员。考虑明确引用默认成员,以提高可读性。
答案 1 :(得分:2)
您所指的三种类型是字典,集合和数组。基本上,这些组合可以构成JSON结构。
有更多时间的人可能会给出更好的答案,但其中的要点是(在我的过度简化的解释中),
为变量指定值会使该值的副本。
Set
用于对象,因为它不会复制对象,而是为对象创建引用。
通常,使用Set将对象引用分配给变量时,不会为该变量创建对象的副本。而是创建对对象的引用。 多个对象变量可以引用同一个对象。因为这些变量是对象的引用而不是对象的副本,所以对象中的任何更改都会反映在引用的所有变量中它即可。但是,在Set语句中使用New关键字时,实际上是在创建对象的实例。 <子>(Source)子>
w3resource:✴Structures of JSON✴
MSDN:Set Statement
MSDN:Declaring Variables
Stack Overflow:What is the opposite of OOP?