• 第4集丨ObjectScript JSON 中 数据类型应用


    写在前面

    为了与大家保持一个愉快的沟通,以及便于描述方便,本文做了一些术语简写,如下:

    • 文章宗旨:尽量不讲废话
    • 文章思路:以总结的方式编写
    • dynEnt:动态实体
    • dynObj:动态对象
    • dynAry:动态数组
    • textConstructor( 文本构造器):文字 JSON 构造函数{}[]
    • jsonStr:文本 JSON 字符串
    • * :表示重点掌握
    • -:废话可忽略

    1. dynEnt成员数据类型

    ObjectScript 没有等同于 JSON truefalsenull 的不同常量,并且 JSON 没有具有未定义值的数组元素的概念。

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

    • 对象数据类型:

      • array — 动态数组引用

      • object — 动态对象引用

      • oref — 对不是动态实体的对象的引用

    • 文本值:

      • number ― 一个规范的数值

      • string — 字符串文本或计算结果为字符串文本的表达式

    • JSON 文本:

      • boolean — JSON 文本真或假

      • null — 一个 JSON 文本 null

    • 无数据类型:

      • unassigned — 未赋值,属性或元素存在,但没有赋值。

    2. 使用 %GetTypeOf() 获取值的数据类型

    2.1 对对象使用 %GetTypeOf

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

       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))}
    
    Datatype of prop1 is number
    Datatype of prop2 is array
    Datatype of prop3 is object
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 对数组使用 %GetTypeOf

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

       set dynarray = [12,34]
       set dynarray."3" = "final"
       write dynarray.%ToJSON()
    [12,34,null,null,"final"]
    
       for index = 0:1:3 {write !,"Datatype of "_index_" is "_(dynarray.%GetTypeOf(index))}
    Datatype of 0 is number
    Datatype of 1 is number
    Datatype of 2 is unassigned
    Datatype of 3 is string
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2 区分数组、对象和 oref

    动态实体的数据类型可以是数组或对象。不是动态实体的系统间 IRIS 对象将是数据类型 oref。在下面的示例中,对象 dyn 的每个属性都是这三种数据类型之一。属性 dynobject 是类%DynamicObject,属性 dynarray%DynamicArray,而属性 streamobj%Stream.GlobalCharacter

       set dyn={"dynobject":{"a":1,"b":2},"dynarray":[3,4],"streamobj":(##class(%Stream.GlobalCharacter).%New())}
       set iterator=dyn.%GetIterator()
       while iterator.%GetNext(.key,.val) { write !, "Datatype of "_key_" is: "_dyn.%GetTypeOf(key) }
    
    Datatype of dynobject is: object
    Datatype of dynarray is: array
    Datatype of streamobj is: oref
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. 使用 %Set() 或 %Push() 覆盖默认数据类型

    默认情况下,系统会自动将 %Set()%Push() 值参数解释为对象数据类型(对象、数组或 oref)或 ObjectScript 文本数据类型(字符串或数字)。您不能直接将 JSON 文本 nulltruefalse 作为值传递,因为该参数被解释为 ObjectScript 文本或表达式。例如,下面的代码引发错误,因为值 true 被解释为变量名称:

       do o.%Set("prop3",true)
    
    DO o.%Set("prop3",true)
    ^
    <UNDEFINED> *true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ObjectScript 使用 “”(空字符串)表示 null0 表示布尔 false,非零数字表示布尔 true。为了解决这个问题,%Set()%Push() 采用可选的第三个参数来指定值的数据类型。第三个参数可以是 JSON 布尔值或 null。例如:

       write {}.%Set("a",(2-4)).%Set("b",0).%Set("c","").%ToJSON()
    {"a":-2,"b":0,"c":""}
    
       write {}.%Set("a",(2-4),"boolean").%Set("b",0,"boolean").%Set("c","","null").%ToJSON()
    {"a":true,"b":false,"c":null}
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

       write [].%Push("023"_"04").%Push(5*5).%ToJSON()
    ["02304",25]
    
       write [].%Push(("023"_"04"),"number").%Push((5*5),"string").%ToJSON()
    [2304,"25"]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4. 解析 JSON 空值和布尔值

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

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

       set test = [true,1,(1=1),false,0,(1=2),"",null]
       write test.%ToJSON()
       
    [true,1,1,false,0,0,"",null]
    
    • 1
    • 2
    • 3
    • 4

    如上所示,构造函数中分配的值已保留在生成的动态数组中,并且在序列化为 JSON 字符串时正确显示。

    下面的示例检索并显示数组值。正如预期的那样,JSON 值 true、false 和 null 将强制转换为与 ObjectScript 兼容的值 1、0 和 “”

       set iter = test.%GetIterator()
       while iter.%GetNext(.key,.val){write "/"_val_"/ "}
       
    /1/ /1/ /1/ /0/ /0/ /0/ // //
    
    • 1
    • 2
    • 3
    • 4

    此示例使用 %GetNext(),但如果使用 %Get()%Pop()点语法检索值,则会得到相同的结果。

    如有必要,可以使用 %GetTypeOf() 方法获取值的原始数据类型。例如:

       set iter = test.%GetIterator()
       while iter.%GetNext(.key,.val) {write !,key_": /"_test.%Get(key)_"/ = "_test.%GetTypeOf(key)}
       
    0: /1/ = boolean
    1: /1/ = number
    2: /1/ = number
    3: /0/ = boolean
    4: /0/ = number
    5: /0/ = number
    6: // = string
    7: // = null
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5. 解析null、空字符串值和未赋值

    尽管可以将 JSON 空值分配给元素或属性,但该值将始终以“”ObjectScript 空字符串)的形式返回。如果尝试获取未赋值元素的值,也会返回空字符串。可以使用 %GetTypeOf() 在每种情况下标识实际数据类型。

    此示例将测试包含 JSON 空值和空字符串的稀疏数组。尽管数组元素 2 没有赋值,但它将在 JSON 字符串中用 null 表示:

       set array = [null,""]
       do array.%Set(3,"last")
       write array.%ToJSON()
       
    [null,"",null,"last"]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在大多数情况下,可以使用 %GetNext() 来检索数组值,但此示例使用 for 循环返回 %GetNext() 将跳过的未赋值值。最后一个元素的索引号是 array.%Size()-1,但循环计数器被特意设置为超过数组的末尾:

       for i=0:1:(array.%Size()) {write !,i_". value="""_array.%Get(i)_""" type="_array.%GetTypeOf(i)}
       
    0. value="" type=null
    1. value="" type=string
    2. value="" type=unassigned
    3. value="last" type=string
    4. value="" type=unassigned
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    • 元素 0 是一个 JSON 空值%GetTypeOf() 将其标识为数据类型 null

    • 元素 1 是一个空字符串,标识为数据类型字符串。

    • 元素 2 没有值,并且标识为未赋值的数据类型。

    • 尽管元素 3 是数组中的最后一个元素,但该示例尝试获取不存在的元素 4 的数据类型,该元素 4 也被标识为未赋值的数据类型。有效的数组索引号将始终小于 array.%Size()

  • 相关阅读:
    Abbkine TraKine Pro 活细胞微管染色试剂盒重要特色
    Java Web学习笔记6——盒子模型
    php 二分查询算法实现
    MySQL入门第六天——函数与条件查询
    剑指offer 70. 圆圈中最后剩下的数字
    线程状态场景模拟以及问题定位
    自动挂载磁盘
    虚拟机安装openEuler系统
    【javaEE】多线程进阶(Part1 锁策略、CAS、synchronized )
    【毕业设计】基于javaEE+SSH+mysql的医院在线挂号系统设计与实现(毕业论文+程序源码)——医院在线挂号系统
  • 原文地址:https://blog.csdn.net/DUQGQG/article/details/125989220