最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 第四章 Caché JSON 处理数据类型

    正文概述 掘金(Cache技术分享)   2020-12-31   480

    第四章 Caché JSON 处理数据类型

    使用%GetTypeOf()返回值的数据类型

    可以使用%GetTypeOf()方法获取动态实体成员的数据类型。动态对象属性或数组元素可以具有下列任何一种数据类型:

    • 对象数据类型:
    1. array 动态数组引用
    2. object 动态对象引用
    3. oref 对不是动态实体的cache对象的引用
    • 文本值:
    1. number 数字
    2. string 字符串或字符串文字的表达式
    • JSON 文本值:
    1. boolean JSON文本 true或 false
    2. null JSON文本 null
    • 没有数据类型:
    1. unassigned 属性或元素存在,但没有赋值。

    对象使用%GetTypeOf

    当对对象使用此方法时,参数是属性的名称。例如:

    /// d ##class(PHA.OP.MOB.Test).TestGetTypeObjects()
    ClassMethod TestGetTypeObjects()
    {
    	set dynobj={"prop1":123,"prop2":[7,8,9],"prop3":{"a":1,"b":2}}
    	set iter = dynobj.%GetIterator()
    	while iter.%GetNext(.name) {write !,"Datatype of "_name_" is "_(dynobj.%GetTypeOf(name))}
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestGetTypeObjects()
     
    Datatype of prop1 is number
    Datatype of prop2 is array
    Datatype of prop3 is object
    

    对数组使用%GetTypeOf

    当对数组使用此方法时,参数是元素的索引。下面的示例研究一个稀疏数组,其中元素2没有赋值。该示例使用for循环,因为%GetNext()将跳过未分配的元素:

    /// d ##class(PHA.OP.MOB.Test).TestGetTypeArray()
    ClassMethod TestGetTypeArray()
    {
    	set dynarray = [12,34]
    	set dynarray."3" = "final"
    	write dynarray.%ToJSON()
    	for index = 0:1:3 {write !,"Datatype of "_index_" is "_(dynarray.%GetTypeOf(index))}
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestGetTypeArray()
    [12,34,null,"final"]
    Datatype of 0 is number
    Datatype of 1 is number
    Datatype of 2 is unassigned
    Datatype of 3 is string
    

    区分数组或对象和oref

    动态实体的数据类型将是数组或对象。不是动态实体的Caché 对象将是数据类型oref。在下面的示例中,对象dyn的每个属性都是这三种数据类型之一。

    属性dynobjectclass %DynamicObject,属性dynarray%DynamicArray,属性streamobj%Stream.GlobalCharacter:

    /// d ##class(PHA.OP.MOB.Test).TestGetTypeOref()
    ClassMethod TestGetTypeOref()
    {
    	s a="字符串"
    	set dyn={"dynobject":{"a":1,"b":2},"dynarray":[3,4],"streamobj":(##class(%Stream.GlobalCharacter).%New()),"a":(a)}
    	set iterator=dyn.%GetIterator()
    	while iterator.%GetNext(.key,.val) { write !, "Datatype of "_key_" is: "_dyn.%GetTypeOf(key) }
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestGetTypeOref()
    Datatype of dynobject is: object
    Datatype of dynarray is: array
    Datatype of streamobj is: oref
    Datatype of a is: string
    

    注意: 在 json字符串中引用Caché oject变量 可以在()中使用

    %Set()%Push()重写覆盖默认数据类型

    默认情况下,Caché 自动将%Set()%Push()值参数解释为对象数据类型(对象、数组或oref)或Caché 文字数据类型(字符串或数字)。

    不能直接将JSON字面量nulltruefalse作为值传递,因为参数被解释为Caché字面量或表达式。

    例如,下面的代码抛出一个错误,因为Caché 将true解释为一个变量名:

    /// d ##class(PHA.OP.MOB.Test).TestDatatype()
    ClassMethod TestDatatype()
    {
       s o={}
       do o.%Set("prop3",true)
       write o.%ToJSON()
    }
    
    DHC-APP> d ##class(PHA.OP.MOB.Test).TestDatatype()
     
       do o.%Set("prop3",true)
       ^
    <UNDEFINED>zTestDatatype+2^PHA.OP.MOB.Test.1 *true
    

    Caché 对null使用“”(一个空字符串),对boolean false使用0,对boolean true使用非零数字。为了处理这个问题,%Set()%Push()使用可选的第三个参数来指定值的数据类型。

    第三个参数可以是JSON boolean,也可以是null。例如:

    /// d ##class(PHA.OP.MOB.Test).TestDatatypeThird()
    ClassMethod TestDatatypeThird()
    {
    	write {}.%Set("a",(2-4)).%Set("b",0).%Set("c","").%ToJSON(),!
    	write {}.%Set("a",(2-4),"boolean").%Set("b",0,"boolean").%Set("c","","null").%ToJSON(),!
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestDatatypeThird()
    {"a":-2,"b":0,"c":""}
    {"a":true,"b":false,"c":null}
    

    第三个参数也可以是字符串或数字,如果值可以解释为一个数字:

    /// d ##class(PHA.OP.MOB.Test).TestDatatypeThirdArgument()
    ClassMethod TestDatatypeThirdArgument()
    {
    	write [].%Push("023"_"04").%Push(5*5).%ToJSON(),!
    	write [].%Push(("023"_"04"),"number").%Push((5*5),"string").%ToJSON(),!
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestDatatypeThirdArgument()
    ["02304",25]
    [2304,"25"]
    

    解析JSON空值和布尔值

    在JSON语法中,值truefalsenull与值10“”(空字符串)不同,但是Caché ObjectScript没有这种区别。当从元素或属性检索JSON值时,总是将它们转换为与object script兼容的值。这意味着JSON true总是返回为1,false为0,null为“”。在大多数情况下,这将是理想的结果,因为返回值可以在Caché 表达式中使用,而无需首先将其从JSON格式转换过来。动态实体在内部保留原始的JSON或Caché 值,因此可以在必要时使用%GetTypeOf()来标识实际的数据类型。

    在下面的示例中,动态数组构造函数指定JSON真、假、空值、数字和字符串文字值,以及ObjectScript动态表达式(计算结果以Caché 布尔值1和0):

    /// d ##class(PHA.OP.MOB.Test).TestBooleanValues()
    ClassMethod TestBooleanValues()
    {
    	set test = [true,1,(1=1),false,0,(1=2),"",null]
    	write test.%ToJSON()
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestBooleanValues()
    [true,1,1,false,0,0,"",null]
    

    正如上面所看到的,构造函数中分配的值被保存在结果的动态数组中,并在序列化为JSON字符串时被正确显示。

    下面的示例检索并显示数组值JSON值truefalsenull被转换为与Caché 兼容的值10“”:

    /// d ##class(PHA.OP.MOB.Test).TestBooleanValues()
    ClassMethod TestBooleanValues()
    {
    	set test = [true,1,(1=1),false,0,(1=2),"",null]
    	write test.%ToJSON(),!
    	set iter = test.%GetIterator()
    	while iter.%GetNext(.key,.val){write "/"_val_"/ ",!}
    }
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestBooleanValues()
    [true,1,1,false,0,0,"",null]
    /1/
    /1/
    /1/
    /0/
    /0/
    /0/
    //
    //
    

    本例使用%GetNext(),但是如果使用%get()%Pop()或点语法检索值,则会得到相同的结果。

    必要时,可以使用%GetTypeOf()方法来发现值的原始数据类型。例如:

    /// d ##class(PHA.OP.MOB.Test).TestBooleanValues()
    ClassMethod TestBooleanValues()
    {
    	set test = [true,1,(1=1),false,0,(1=2),"",null]
    	write test.%ToJSON(),!
    	set iter = test.%GetIterator()
    	while iter.%GetNext(.key,.val){write "/"_val_"/ ",!}
    	set iter = test.%GetIterator()
        while iter.%GetNext(.key,.val) {write !,key_": /"_test.%Get(key)_"/ = "_test.%GetTypeOf(key)}
    }
    
    
    DHC-APP>d ##class(PHA.OP.MOB.Test).TestBooleanValues()
    [true,1,1,false,0,0,"",null]
    /1/
    /1/
    /1/
    /0/
    /0/
    /0/
    //
    //
     
    0: /1/ = boolean
    1: /1/ = number
    2: /1/ = number
    3: /0/ = boolean
    4: /0/ = number
    5: /0/ = number
    6: // = string
    7: // = null
    

    注意:动态对象中的数据类型。 虽然本章主要讨论动态数组,但是相同的数据类型转换也适用于动态对象值。如果将动态数组测试定义为动态对象,则本节中的示例将完全相同:

    set test = {"0":true,"1":1,"2":(1=1),"3":false,"4":0,"5":(1=2),"6":"","7":null}
    

    除了这一行之外,示例代码都不需要修改。此对象中的属性名是与原始数组的索引号对应的数字字符串,因此即使输出也是相同的。

    解决Null、空字符串和未赋值

    尽管可以将JSON null值赋给元素或属性,但该值总是以“”(Caché空字符串)的形式返回。如果试图获取未分配元素的值,也将返回空字符串。可以使用%GetTypeOf()来识别每种情况下的实际数据类型。

    本例将测试一个包含JSON null值和空字符串的稀疏数组。虽然数组元素2没有赋值,但它在JSON字符串中表示为null:

    /// d ##class(PHA.OP.MOB.Test).TestArrayNull()
    ClassMethod TestArrayNull()
    {
    	set array = [null,""]
    	do array.%Set(3,"last")
    	write array.%ToJSON()
    }
    
    DHC-APP> d ##class(PHA.OP.MOB.Test).TestArrayNull()
    [null,"",null,"last"]
    

    在大多数情况下,将使用%GetNext()来检索数组值,但是本例使用for循环来返回未分配的值,而%GetNext()将跳过这些值。

    最后一个元素的索引号是array.%Size()-1,但是循环计数器被故意设置为超过数组的末尾:

    /// d ##class(PHA.OP.MOB.Test).TestArrayNull()
    ClassMethod TestArrayNull()
    {
    	set array = [null,""]
    	do array.%Set(3,"last")
    	write array.%ToJSON(),!
    	
    	for i=0:1:(array.%Size()) {write !,i_". value="""_array.%Get(i)_""" type="_array.%GetTypeOf(i)}
    }
    
    DHC-APP> d ##class(PHA.OP.MOB.Test).TestArrayNull()
    [null,"",null,"last"]
     
    0. value="" type=null
    1. value="" type=string
    2. value="" type=unassigned
    3. value="last" type=string
    4. value="" type=unassigned
    

    在本例中,%Get()在四种不同的情况下返回空字符串:

    • 元素0是一个JSON空值,%GetTypeOf()将其标识为数据类型null
    • 元素1是一个空字符串,它被标识为数据类型字符串。
    • 元素2没有值,被标识为未分配的数据类型。
    • 虽然元素3是数组中的最后一个元素,但是示例尝试为不存在的元素4获取一个数据类型,该元素也被标识为未分配的数据类型。有效的数组索引号总是小于array.%Size()

    注意:nullunassigned之间的区别是Caché 元数据,当动态实体序列化为JSON字符串时,这些元数据不会被保留。所有未分配的元素都将序列化为null值。


    起源地下载网 » 第四章 Caché JSON 处理数据类型

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元