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命令定义变量。大多数情况下,命令和函数在使用前都需要定义变量,如果变量未定义,则默认情况下,引用它会生成 <UNDEFINED>报错
//输出Error <UNDEFINED>
set x = y
  • 变量可以不被指定类型,可以接收任何数值

2.变量类型

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

2.1 局部变量

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

 2.2 百分比变量

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

/// d ##class(Demo.Test).MyFunction1()
ClassMethod MyFunction1()
{
	set num = 1
	set %za = "a"
	
	w %za,!
	w num,!
}

/// d ##class(Demo.Test).MyFunction2()
ClassMethod MyFunction2()
{
	w %za,!
	w num,!
}

}

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

DHC-APP>d ##class(Demo.Test).MyFunction2()
 d ##class(Demo.Test).MyFunction2()
^
<SYNTAX>
DHC-APP>d ##class(Demo.Test).MyFunction1()
a
1
DHC-APP>d ##class(Demo.Test).MyFunction2()
a
 w num,! }
 ^
<UNDEFINED>zMyFunction2+3^Demo.Test1.1 *num
  •   通常复用一些固定配置的时候,会使用百分比变量
q:($data($zconfig))

set %zconfig = ##class(xx).xx()

2.3 ProcedureBlock(过程块)

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

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

Class Demo.Test Extends %RegisteredObject
{

/// d ##class(Demo.Test).MyFunction1()
ClassMethod MyFunction1()
{
	for i=1 : 1 : 5{
		d ..MyFunction2()
	}
}

ClassMethod MyFunction2()
{
	set i = 2
	w "i="_i_",this is a not procedureblock",!
}
}

        执行命令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后,如下所示:

Class Demo.Test Extends %RegisteredObject [ Not ProcedureBlock ]
{

/// d ##class(Demo.Test).MyFunction1()
ClassMethod MyFunction1()
{
	for i=1 : 1 : 5{
        d ..MyFunction2()
    }
}

ClassMethod MyFunction2()
{
	set i = 2
    //程序会陷入死循环,一直不停输出:i=2,this is a not procedureblock
	w "i="_i_",this is a not procedureblock",!
}
}

         调用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进程访问,该变量在进程终止时会自动删除。定义进程私有全局变量如下所示:
set ^||num = 2
set ^||name = "Jack"
  • 任何命名空间都可以访问该变量
ClassMethod MyFunction2()
{
	kill ^||num
	set ^||num = 2
	//输出^||num = 2
	zw ^||num
	//输出2
	w ^||num
	
	//切换命名空间
	set $namespace = "DHC-APP"
	//输出^||num = 2
	zw ^||num
	//输出2
	w ^||num
}
  • 各个方法之间可以访问进程私有全局变量
/// d ##class(Demo.Test).MyFunction6()
ClassMethod MyFunction6()
{
	
	set ^||num = 1
	d ..MyFunction7()
}

ClassMethod MyFunction7()
{
    //输出1
	w ^||num
}
  • 进程私有全局变量对于临时储存大数据值特别有用
  • 回滚事务时,对进程私有全局变量这些没有任何影响,即回滚事务时,对进程私有全局变量操作不会被回滚
ClassMethod MyFunction()
{
	set ^||num = 1
	
	//开启事务
	ts 
		set ^||num = 2
	
	//回滚
	tro
		w ^||num,!
}
  • 名称限制为31个字符。可以指定长度超过31个字符的名称,但是只有前31位有效。
ClassMethod MyFunction3()
{
	
	set ^||abcabcdwewesssyygsoshbsdvv2233a = 1
	set ^||abcabcdwewesssyygsoshbsdvv2233ab = 3
	
	// 输出3
	w ^||abcabcdwewesssyygsoshbsdvv2233a
    // 输出3
    w ^||abcabcdwewesssyygsoshbsdvv2233ab
}

2.5 使用^GETPPGINFO

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

2.6 全局变量(Global)

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

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

2.7 数组变量与下标变量

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

//下标变量
set ^x("a") = 2
//下标变量
set color("red") = "red"

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

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

2.9 对象属性

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

Class Demo.First Extends %RegisteredObject
{
 
/// 声明属性
Property name As %String;
 
/// d ##class(Demo.First).Variable()
ClassMethod Variable()
{
    /// 初始化一个对象
	set obj = ..%New()
    /// 设置属性值
	set obj.name = "Jack"
	
    //输出Jack
	w obj.name
}
 
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckyliuqs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值