ABAP中的枚举对象
枚举对象是枚举类型的数据对象。枚举对象只能包含类型为枚举类型的枚举值。ABAP从版本7.51开始支持它们。
这是一种常见的模式。在ABAP 7.51之前,人们通常用如下方式实现类似的功能:
CLASS cx_wrong_size DEFINITION INHERITING FROM cx_static_check.
ENDCLASS. CLASS shirt DEFINITION.
PUBLIC SECTION.
TYPES tsize TYPE i.
CONSTANTS:
size_s TYPE tsize VALUE ,
size_m TYPE tsize VALUE ,
size_l TYPE tsize VALUE ,
size_xl TYPE tsize VALUE .
METHODS
constructor IMPORTING size TYPE tsize
RAISING cx_wrong_size.
...
PRIVATE SECTION.
DATA
size TYPE tsize.
ENDCLASS. CLASS shirt IMPLEMENTATION.
METHOD constructor.
IF size <> size_s AND
size <> size_m AND
size <> size_l AND
size <> size_xl.
RAISE EXCEPTION TYPE cx_wrong_size.
ENDIF.
me->size = COND #(
WHEN size <> size_s AND
size <> size_m AND
size <> size_l AND
size <> size_xl THEN THROW cx_wrong_size( )
ELSE size ).
ENDMETHOD.
ENDCLASS.
这里,size属性只可以是shirt类中定义的常量中的值。其它值会导致异常。用户创建shirt类时,需要这样做:
TRY.
DATA(shirt) = NEW shirt( shirt=>size_xl ).
CATCH cx_wrong_size.
...
ENDTRY.
看到开销了吗?为什么不让运行时环境来为你做值检查呢?有一种叫做枚举和枚举类型的概念(可以在这种情况下应用)。
在7.51以及更高的版本里,ABAP也会支持枚举概念。如果使用枚举类型来重写上面的例子的话:
CLASS shirt DEFINITION.
PUBLIC SECTION.
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize.
METHODS
constructor IMPORTING size TYPE tsize.
...
PRIVATE SECTION.
DATA
size TYPE tsize.
ENDCLASS. CLASS shirt IMPLEMENTATION.
METHOD constructor.
me->size = size.
ENDMETHOD.
ENDCLASS.
TYPES语句的一个新变式:BEGIN OF ENUM – END OF ENUM,它可以围起一个常量的集。常量的标准基本类型是i并且枚举值从0开始计数。
像上文那样使用的话:
DATA(shirt) = NEW shirt( shirt=>size_xl ).
不过,使用了枚举对象后,你不再需要处理异常了。如果你传递一个非法值的话,会得到语法错误!
DATA(shirt) = NEW shirt( ).

枚举是类型和常量的混合体。通过BEGIN OF ENUM enum – END OF ENUM enum 你声明了一个可以在TYPE附加项后声明的基本类型enum。在它们之间,你可以声明一个常量集,它们叫做枚举常量。这样就定义了拥有enum类型的枚举对象所允许的枚举值。在这里,TYPES实际上就和CONSTANTS语句一样。
ABAP运行时环境会检查只有被允许的枚举值可以被赋给枚举对象。
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA size TYPE tsize.
size = size_xl. "允许 DATA dobj LIKE size.
dobj = size. "允许 dobj = . "语法或运行时错误
枚举对象只能赋值给拥有相同枚举类型的枚举对象。同样,枚举对象间的比较也只能在相同类型的枚举对象间发生。当然,枚举常量本身也包含在内。
通常,你一点也不关心枚举对象的内容。枚举对象的语义由枚举常量来定义。然而,你也可以将枚举类型定义为i类型之外的其它基本类型,并且拥有其它枚举值(其中一个必须是初始值):
TYPES:
basetype TYPE c LENGTH ,
BEGIN OF ENUM tsize BASE TYPE basetype,
size_i VALUE IS INITIAL,
size_s VALUE `S`,
size_m VALUE `M`,
size_l VALUE `L`,
size_xl VALUE `XL`,
END OF ENUM tsize. DATA size TYPE tsize.
size = size_xl. "允许 DATA dobj LIKE size.
dobj = size."允许
这使你可以轻松地把现有“枚举值”转换为新方式的枚举值。运气好的话,可以不需要调整它们的使用。
如果你在一个上下文中有超过一个枚举类型,你可以将各个枚举值组织到结构里:
TYPES:
BEGIN OF ENUM tsize STRUCTURE size,
s,
m,
l,
xl,
END OF ENUM tsize STRUCTURE size. DATA dobj TYPE tsize.
dobj = size-xl. "允许
以上代码定义了一个枚举结构size。结构的组件是枚举类型的枚举常量。
枚举对象的常见用处是比较它和枚举常量以决定程序需要切换到哪一个功能分支:
TYPES:
BEGIN OF ENUM tsize STRUCTURE size,
s,
m,
l,
xl,
END OF ENUM tsize STRUCTURE size. DATA dobj TYPE tsize. ... CASE dobj.
WHEN size-s.
...
WHEN size-m.
...
WHEN size-l.
...
WHEN size-xl.
...
ENDCASE.
除此之外,还有一些可以应用的情况:
你可以将枚举对象赋给一个c类型或者string类型的文本。结果就是定义了枚举值的枚举常量的名字。
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA text TYPE string.
text = size_xl.
cl_demo_output=>display( text ). "结果是SIZE_XL
也可以写作:
DATA(text) = CONV string( size_xl ).
可以使用CONV操作符指定类型来访问当前值:
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA(value) = CONV i( size_xl ) .
cl_demo_output=>display( value ). "输出结果是3
另一种方式是,可以使用CONV将一个有效的枚举值转换为枚举对象(常规的赋值语句是无法做到的):
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA(num) = . TRY.
DATA(dobj) = CONV tsize( num ) .
cl_demo_output=>display( dobj ). "Output is SIZE_XL
CATCH cx_sy_conversion_no_enum_value.
...
ENDTRY.
RTTI中也多了一个相应的类CL_ABAP_ENUMDESCR:
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA(size) = VALUE tsize( ). DATA(enum_descr) = CAST cl_abap_enumdescr(
cl_abap_typedescr=>describe_by_data( size ) ). cl_demo_output=>new(
)->write_data( enum_descr->kind "E, for elementary
)->write_data( enum_descr->type_kind "k, new for enumerated type
)->write_data( enum_descr->base_type_kind "I, the base type
)->write_data( enum_descr->members "Table of constants and values
)->display( ).
基本上就是这些内容了。
躺下让ABAP运行时来为你工作吧。要注意枚举类型只能在某些合适的运算位置中出现,并且只能包含预先规定的值。非法的枚举值永远不会在枚举对象中出现。
PS:原文的评论中有人提到,枚举值和数据字典中的domain的固定值很像,为什么二者没有集成关系?
作者的回答是:这个特性实际上已经在设计中了,很有希望出现。具体情况要视资源和优先级而定。
本文链接:http://www.cnblogs.com/hhelibeb/p/7976078.html
英文原文:ABAP News for Release 7.51 – Enumerations
ABAP中的枚举对象的更多相关文章
- java 根据值获取枚举对象
关键方法: /** * 值映射为枚举 * * @param enumClass 枚举类 * @param value 枚举值 * @param method 取值方法 * @param <E&g ...
- JS基础_枚举对象中的属性
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 枚举对象中的属性 for . . in
枚举对象中的属性:把对象中所有的属性和值都取出来 使用 for . . . in 语句 语法: for(var 变量 in 对象){ } for . . . in 语句 对象中有几个属性,循 ...
- 第三章 EnumUtil根据值获取枚举对象
项目中使用枚举类的好处这里不再赘述,在使用枚举值时,通常需要根据值来获取枚举对象,下面介绍两种实现方案: 1.在枚举类中定义方法实现 首先给出如下性别枚举类: public enum SexEnum ...
- 【译】Java中的枚举
前言 译文链接:http://www.programcreek.com/2014/01/java-enum-examples/ Java中的枚举跟其它普通类很像,在其内部包含了一堆预先定义好的对象集合 ...
- 重温WCF之数据契约中使用枚举(转载)(十一)
转载地址:http://www.zhuli8.com/wcf/EnumMember.html 枚举类型的定义总是支持序列化的.当我们定义一个新的枚举时,不必应用DataContract特性,就可以在数 ...
- 说说Java中的枚举(一)
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”. ...
- 字符串处理:ABAP中的正则表达式
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- ruby中迭代器枚举器的理解
参考<ruby编程语言>5.3迭代器和可枚举对象 迭代器一个迭代器是一个方法,这个方法里面有yield语句,这个方法里的yield语句,与传递给这个方法的块进行数据传输 yield将数据传 ...
随机推荐
- markdown简述
前端开发的工具 编辑器: 1. 轻量级的,依靠插件:sublime:atom(github):vs code(miscrosaft) 2. 集成的:DW:webstorm:hbuild ...
- 最大似然估计 (Maximum Likelihood Estimation), 交叉熵 (Cross Entropy) 与深度神经网络
最近在看深度学习的"花书" (也就是Ian Goodfellow那本了),第五章机器学习基础部分的解释很精华,对比PRML少了很多复杂的推理,比较适合闲暇的时候翻开看看.今天准备写 ...
- JS获取URL参数的值
function getQueryValue (key) { const reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', ' ...
- eclipse环境下基于已构建struts2项目整合spring+hibernate
本文是基于已构建的struts2项目基础上整合 spring+hibernate,若读者还不熟悉struts2项目,请先阅读 eclipse环境下基于tomcat-7.0.82构建struts2项目 ...
- JAVA 中LinkedHashMap要点记录
JAVA 中LinkedHashMap要点记录 构造函数中可能出现的几个参数说明如下: 1.initialCapacity 初始容量大小,使用无参构造方法时,此值默认是16 2.loadFactor ...
- QuickTime视频解析问题
在QuickTime中可以解析出视频并播放视频,解析的格式后缀名为.mov,之后将该视频导入到Unity Project中,显示未解析到视频文件,本来应该会自动生成MovieTexture材质,但是并 ...
- 实现JavaScript forEach
function forEach(list, callback){ ; n <list.length; n++){ callback.call(list[n], n); } } ,,,,,,,] ...
- leetcode算法题1: 两个二进制数有多少位不相同?异或、位移、与运算的主场
/* The Hamming distance between two integers is the number of positions at which the corresponding b ...
- yum中$releasever、 $basearch等变量含义
[root@kickstart ~]# rpm -qf /etc/redhat-release centos-release--4.1708.el7.centos.x86_64 yum中的$relea ...
- 开源:Sagit.Framework For IOS 开发框架
一:创造Sagit开发框架的起因: 记得IT连创业刚进行时,招了个IOS的女生做开发,然后: ----------女生的事故就此开始了----------- 1:面试时候:有作品,态度也不错,感觉应该 ...