• M语言-变量


    目录

    1.变量概述

    2.变量类型

    2.1 局部变量

     2.2 百分比变量

    2.3 ProcedureBlock(过程块)

    2.4 进程私有全局变量

    2.5 使用^GETPPGINFO

    2.6 全局变量(Global)

    2.7 数组变量与下标变量

    2.8 特殊变量(也称为系统变量)

    2.9 对象属性

    3.变量类型和转换


    1.变量概述

    • 在ObjectScript中,变量是在内存运行时,值的位置的名称,也就是说变量存在内存中。
    • 必须使用set命令定义变量。大多数情况下,命令和函数在使用前都需要定义变量,如果变量未定义,则默认情况下,引用它会生成 报错
    1. //输出Error
    2. set x = y
    • 变量可以不被指定类型,可以接收任何数值

    2.变量类型

            变量分为:局部变量、百分比变量、ProcedureBlock、进程私有全局变量、全局变量、数组变量、特殊变量

    2.1 局部变量

    •  局部变量是储存在当前Cache进程中的变量
    • 只有创建它的Cache进程才能访问,该变量在进程终止时自动删除
    • 任何命名空间可以访问局部变量。
    • 在方法中定义的局部变量只能在该方法中使用
    • 在事务中,不会将局部变量set或kill视为日志记录的事务事件,即回滚事务时,对局部变量的操作不会被回滚,如下所示:
    1. ClassMethod MyFunction()
    2. {
    3. set num = 1
    4. //开启事务
    5. ts
    6. set num = 2
    7. //回滚
    8. tro
    9. // 输出2
    10. w num,!
    11. }
    • 局部变量名称限制为31个字符。可以指定长度超过31个字符的名称,但是只有前31位有效。
    1. ClassMethod MyFunction3()
    2. {
    3. set abcabcdwewesssyygsoshbsdvv2233a = 1
    4. set abcabcdwewesssyygsoshbsdvv2233ab = 3
    5. // 输出3
    6. w abcabcdwewesssyygsoshbsdvv2233a
    7. // 输出3
    8. w abcabcdwewesssyygsoshbsdvv2233ab
    9. }

     2.2 百分比变量

    •  以%开头的变量称为百分比变量。
    • 只有以%Z或者%z开头的变量才可用于应用程序代码,其他百分比变量保留给系统使用。
    1. /// d ##class(Demo.Test).MyFunction1()
    2. ClassMethod MyFunction1()
    3. {
    4. set %za = "a"
    5. // 输出a
    6. w %za
    7. }
    •  与局部变量不同的是,在方法中定义的局部变量只能在该方法中使用,而在方法中定义的百分比变量,可以在其他方法中使用,类似于全局变量效果
    1. Class Demo.Test Extends %RegisteredObject
    2. {
    3. /// d ##class(Demo.Test).MyFunction1()
    4. ClassMethod MyFunction1()
    5. {
    6. set num = 1
    7. set %za = "a"
    8. w %za,!
    9. w num,!
    10. }
    11. /// d ##class(Demo.Test).MyFunction2()
    12. ClassMethod MyFunction2()
    13. {
    14. w %za,!
    15. w num,!
    16. }
    17. }

             程序的运行结果如下所示:

    1. DHC-APP>d ##class(Demo.Test).MyFunction2()
    2. d ##class(Demo.Test).MyFunction2()
    3. ^
    4. DHC-APP>d ##class(Demo.Test).MyFunction1()
    5. a
    6. 1
    7. DHC-APP>d ##class(Demo.Test).MyFunction2()
    8. a
    9. w num,! }
    10. ^
    11. zMyFunction2+3^Demo.Test1.1 *num
    •   通常复用一些固定配置的时候,会使用百分比变量
    1. q:($data($zconfig))
    2. set %zconfig = ##class(xx).xx()

    2.3 ProcedureBlock(过程块)

    • 私有变量。程序块中使用的任何变量都自动成为私有变量,并且只在该程序快中可见。
    • 默认情况下,创建的所有对象方法都使用过程块(默认情况下创建的类,定义了类关键字ProcedureBlock),因此,默认情况下,在方法中创建的所有变量都是私有变量(方法互相之间不能访问),不能对私有变量使用new命令
    • 手动添加Not ProcedureBlock后,局部变量作用域就会变成类似于全局变量效果,即各个方法中创建的变量可以互相访问和修改。

            如下所示:默认情况下,创建的类中都是包含了ProcedureBlock

    1. Class Demo.Test Extends %RegisteredObject
    2. {
    3. /// d ##class(Demo.Test).MyFunction1()
    4. ClassMethod MyFunction1()
    5. {
    6. for i=1 : 1 : 5{
    7. d ..MyFunction2()
    8. }
    9. }
    10. ClassMethod MyFunction2()
    11. {
    12. set i = 2
    13. w "i="_i_",this is a not procedureblock",!
    14. }
    15. }

            执行命令d ##class(Demo.Test).MyFunction1(),打印结果如下:只打印5次:i=2,this is a not procedureblock

    i=2,this is a not procedureblock
    i=2,this is a not procedureblock
    i=2,this is a not procedureblock
    i=2,this is a not procedureblock
    i=2,this is a not procedureblock

            由此可见,默认情况下,在方法中创建的所有变量都是私有变量(方法互相之间不能访问)。

            如果给类定义了Not ProcedureBlock后,如下所示:

    1. Class Demo.Test Extends %RegisteredObject [ Not ProcedureBlock ]
    2. {
    3. /// d ##class(Demo.Test).MyFunction1()
    4. ClassMethod MyFunction1()
    5. {
    6. for i=1 : 1 : 5{
    7. d ..MyFunction2()
    8. }
    9. }
    10. ClassMethod MyFunction2()
    11. {
    12. set i = 2
    13. //程序会陷入死循环,一直不停输出:i=2,this is a not procedureblock
    14. w "i="_i_",this is a not procedureblock",!
    15. }
    16. }

             调用d ##class(Demo.Test).MyFunction1(),会一直不停的打印:i=2,this is a not procedureblock,MyFunction2()中修改了MyFunction1()中变量i的值

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    i=2,this is a not procedureblock

    ......

    2.4 进程私有全局变量

    • 仅可由创建它的Cache进程访问,该变量在进程终止时会自动删除。定义进程私有全局变量如下所示:
    1. set ^||num = 2
    2. set ^||name = "Jack"
    • 任何命名空间都可以访问该变量
    1. ClassMethod MyFunction2()
    2. {
    3. kill ^||num
    4. set ^||num = 2
    5. //输出^||num = 2
    6. zw ^||num
    7. //输出2
    8. w ^||num
    9. //切换命名空间
    10. set $namespace = "DHC-APP"
    11. //输出^||num = 2
    12. zw ^||num
    13. //输出2
    14. w ^||num
    15. }
    • 各个方法之间可以访问进程私有全局变量
    1. /// d ##class(Demo.Test).MyFunction6()
    2. ClassMethod MyFunction6()
    3. {
    4. set ^||num = 1
    5. d ..MyFunction7()
    6. }
    7. ClassMethod MyFunction7()
    8. {
    9. //输出1
    10. w ^||num
    11. }
    • 进程私有全局变量对于临时储存大数据值特别有用
    • 回滚事务时,对进程私有全局变量这些没有任何影响,即回滚事务时,对进程私有全局变量操作不会被回滚
    1. ClassMethod MyFunction()
    2. {
    3. set ^||num = 1
    4. //开启事务
    5. ts
    6. set ^||num = 2
    7. //回滚
    8. tro
    9. w ^||num,!
    10. }
    • 名称限制为31个字符。可以指定长度超过31个字符的名称,但是只有前31位有效。
    1. ClassMethod MyFunction3()
    2. {
    3. set ^||abcabcdwewesssyygsoshbsdvv2233a = 1
    4. set ^||abcabcdwewesssyygsoshbsdvv2233ab = 3
    5. // 输出3
    6. w ^||abcabcdwewesssyygsoshbsdvv2233a
    7. // 输出3
    8. w ^||abcabcdwewesssyygsoshbsdvv2233ab
    9. }

    2.5 使用^GETPPGINFO

    •  使用^GETPPGINFO可以以块为单位,显示当前进程私有全局变量及其控件分配。会列出进程私有全局变量的下标或值。
    • 可以通过指定进程ID(PID)来显示特定进程私有全局变量;也可以通过指定“*”字符串通配符来显示所有进程的进程私有全局变量
    • 必须在%SYS命名空间才能调用^GETPPGINFO

    2.6 全局变量(Global)

    • 自动储存在Cache数据库中的永久变量。局部变量和进程私有全局变量都是写入内存中,全局变量是写入磁盘中。定义全局变量如下:
    1. ClassMethod MyFunction4()
    2. {
    3. //定义局部变量
    4. set myLocal = "这是局部变量"
    5. //定义全局变量
    6. set ^myGlobal = "这是存储在当前命名空间的全局变量"
    7. //输出^myGlobal="这是存储在当前命名空间的全局变量"
    8. zw ^myGlobal
    9. }
    • 全局变量(Global)是一个B+树
    • 任何进程可以访问全局变量,并且在创建它的进程终止后持续存在,直到被删除。
    • 全局变量被映射到特定的命名空间,并且只有创建该全局变量的命名空间才能访问,如果其他命名空间需要访问,则需要使用扩展引用
    • 将全局变量的设置或终止视为日志记录的事务事件,即回滚事务时,将撤销这些操作。
    1. ClassMethod MyFunction9()
    2. {
    3. set ^myGlobal = 1
    4. ts
    5. set ^myGlobal = 2
    6. tro
    7. //输出^myGlobal=1
    8. zw ^myGlobal
    9. }
    • 同样的,名称限制为31个字符。可以指定长度超过31个字符的名称,但是只有前31位有效。
    1. ClassMethod MyFunction10()
    2. {
    3. set ^abcabcdwewesssyygsoshbsdvv2233a = 1
    4. set ^abcabcdwewesssyygsoshbsdvv2233ab = 2
    5. //输出^abcabcdwewesssyygsoshbsdvv2233a=2
    6. zw ^abcabcdwewesssyygsoshbsdvv2233a
    7. //输出^abcabcdwewesssyygsoshbsdvv2233a=2
    8. zw ^abcabcdwewesssyygsoshbsdvv2233ab
    9. }
    • 可以使用$ZREFERENCE来确定最近使用的全局变量名称;$QSUBSCRIPT返回指定全局变量节点的名称;$QLENGTH返回下标的数量
    • 对于当前进程,局部变量名必须是唯一的,其他进程可以具有同名的局部变量。进程全局变量或全局变量可以与局部变量、百分比变量同名。如下所示: xy、%xy、^||xy和^xy是四个不同的变量
    1. ClassMethod MyFunction11()
    2. {
    3. //定义局部变量
    4. set xy = 1
    5. //定义百分比变量
    6. set %xy = 2
    7. //定义进程私有全局变量
    8. set ^||xy = 3
    9. //定义全局变量
    10. set ^xy = 4
    11. //输出xy=1
    12. zw xy
    13. //输出%xy=2
    14. zw %xy
    15. //输出^||xy=3
    16. zw ^||xy
    17. //输出^xy=4
    18. zw ^xy
    19. }
    • 推荐变量使用的顺序

            局部变量(效率最高)、进程全局变量、全局变量。百分比变量看情况使用

    2.7 数组变量与下标变量

    • 局部变量、进程私有变量和全局变量都可以采用下标
    • 下标名称的最大长度为511个编码字节,超过最大下标长度将会报错;允许的最长整数为309位,超过此限制将会导致错误,因此,必须将长度超过309个字符的数字下标指定为字符串。
    • 局部变量的最大下标级别数为255,;全局变量或进程私有全局变量的最大下标级别数位253.超过最大下标级别数会导致错误
    1. //级别数为3
    2. set ^||xy("a","b","c") = 2
    • 下标为数字的为数组变量,下标不为数字的为下标变量。下标变量包含数组变量。
    1. //数组变量
    2. set ^x(1) = 1
    3. //下标变量
    4. set ^x("a") = 2
    5. //下标变量
    6. set color("red") = "red"

    2.8 特殊变量(也称为系统变量)

    • 一组特殊的内置变量,其中包含Cache操作环境的特定方面的值,Cache定义了所有特殊变量;Cache将所有特殊变量设置为初始值(有时为空字符串值),一些特殊变量可以由用户设置,其他变量只能由Cache设置。特殊变量不是数组变量。
    1. ClassMethod MyFunction12()
    2. {
    3. //输出66330,71864
    4. w $Horolog,!
    5. /*
    6. 输出版本号:Cache for Windows (x86-64) 2016.2
    7. (Build 736_0_16871U) Wed Dec 21 2016 09:38:49 EST
    8. */
    9. w $zversion
    10. }

    2.9 对象属性

            与对象的特定实例相关联并存储在其中的值

    1. Class Demo.First Extends %RegisteredObject
    2. {
    3. /// 声明属性
    4. Property name As %String;
    5. /// d ##class(Demo.First).Variable()
    6. ClassMethod Variable()
    7. {
    8. /// 初始化一个对象
    9. set obj = ..%New()
    10. /// 设置属性值
    11. set obj.name = "Jack"
    12. //输出Jack
    13. w obj.name
    14. }
    15. }

    3.变量类型和转换

            如下所示:

    fromto规则
    NumberString使用表示数字值的字符串,例如“2.6”
    StringNumber字符串的前导字符串被解释为数字文字,例如"-6.21abs34"被解释为-6.21,而"ab2sc22"被解释为0
    ObjectNumber使用给定对象引用的内部对象实例编号,该值为整数
    ObjectString

    使用n@cls形式得字符串,其中n是内部对象实例编号,cls是给定对象的类名

    ClassMethod MyFunction14()
    {
        /// 初始化一个对象
        set ^obj = ..%New()
      
        //输出^obj="10@Demo.Test"
        zw ^obj
    }

    NumberObject不允许
    StringObject不允许

     

    感谢:麦当劳好利来的个人空间_哔哩哔哩_Bilibili

  • 相关阅读:
    mysql高阶语句(一)
    Git企业开发级讲解(五)
    docker启动tomcat容器实例,浏览器访问失败
    nuxt3正确使用keepalive页面缓存组件缓存
    Flux、Mono、Reactor 实战(史上最全)
    『现学现忘』Docker基础 — 23、使用Docker安装Tomcat
    ​软考-高级-系统架构设计师教程(清华第2版)【第7章 系统架构设计基础知识(263~285)-思维导图】​
    鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
    D. Yet Another Problem(异或/位运算/二分)
    黑马笔记---常用API
  • 原文地址:https://blog.csdn.net/qq_35507234/article/details/126217148