文章来自:iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天 (ithome.com.tw)
[day22]TYPE/FUNCTION/INTERFACE让FGL更贴近对象语言
TYPE
定义基本或结构化数据类型
从 Genero 2.50开始,原先的 DEFINE定义区块,开始支持 TYPE。这是可以结构化定义数组(RECORD)。然后在需要的地方调用。
PRIVATE TYPE type_abc RECORD
col01 VARCHAR(100),
col02 LIKE table_A.col02
END RECORD
PUBLIC TYPE type_desk RECORD #桌子
length INT, #长
height INT, #高
shape RECORD
drawer INT #抽屉数
END RECORD
END RECORD
DEFINE desk1 type_desk #命名一个 desk1
利用这样的结构,可以在程序的任何地方轻松地生成结构,调整的时候也可避免到处调整。最前端的 PUBLIC/PRIVATE则是标示了:当这支4GL被 IMPORT的时候,能否在引用作业中直接调用TYPE
当 TYPE到 Genero 3.20以后的版本,开始支持 ATTRIBUTES 属性配置,可以搭配 REST WEB SERVICE的配置,这部分暂时略过不提
FUNCTION
函式名称定义。
其实 FUNCTION 从 Genero 3.0开始不断的在增加新语法,除了原先单纯定义之外还有下列的新语法(Genero3.X以后支持,旧版本无法编译此新语法):
语法1
PUBLIC FUNCTION func_abc( input_var )
透过这样的语法,因为是 PUBLIC 的,所以可以在任何 42m 调动此 function_abc,且传入参数 input_var
语法2
PUBLIC FUNCTION func_abc( input_var INT, comm_var INT INOUT ) RETURNS (INT, INT)
从Genero 3.20开始,在设定传入参数的时候可以一并指定型态,这样可以减少DEFINE的量。但此处不可使用 LIKE的方式指定。INOUT标定该参数同时传入传出,使用 CALL BY REFERENCE的做法。
最后的 RETURNS (**注意不是RETURN 也不是 RETURNING **),则是标定回传应为两个 INT,做编译时的型别检查用。(单一个的时候,不需要加上括号)
语法3则直接上范例进行解说
TYPE Rectangle RECORD #定义一个矩形
height, width DOUBLE PRECISION #存在长、宽 双精度数值
END RECORD
#下面的 FUNCTION在定义 对象(TYPE)所需要的 "方法"
# 物件 r 的 TYPE为 Rectangle
# 方法:算面积 回传 面积的双精度数值
FUNCTION (r Rectangle) area() RETURNS DOUBLE PRECISION
RETURN r.height * r.width #算法是长 x 宽
END FUNCTION
所以 TYPE可以是一个对象定义,透过 FUNCTION 绑上该对象可操作的方法,接着就可以操作为
DEFINE a Rectangle
LET a.height = 10
LET a.width = 20
DISPLAY a.area() #出现 200
此处需要特别注意,『变量名称』和『方法名称』不可以一样,否则会出现 -8427 的错误
| Method and field names must be different. Type rectangle.Rectangle has field width.
| See error number -8427.
然后 FUNCTION 后方的 RETURNS 一定要标注(没回传也要标注),否则会出现 -8431的错误
| A method without return type (RETURNS) can not return values.
| See error number -8431.
INTERFACE
** GENERO 3.20以后版本提供 **
变量可以透过数组(RECORD),预先定义出结构(TYPE):那一堆类似的方法(METHOD)可以预先定义出结构吗?那叫做什么?
对,可以的,那就叫做 INTERFACE。
接续上一个四边形(Rectangle)的范例进行
TYPE Shape INTERFACE #结构化一个”接口”
area() RETURNS FLOAT, #内含两种方法
kind() RETURNS STRING
END INTERFACE
准备好之后,就可以使用了:
DEFINE r Rectangle = ( height:10, width:20 ) #定义顺便直接将数值带入
DEFINE v1 Shape #取用 Shape 这个方法集
LET v1 = r #这个 INTERFACE 选用的是 r (Rectangle)
DISPLAY v1.area() #直接调动 INTERFACE内的 .area() 方法
对的,为了适应对象的方法,DEFINE可以直接将需要的元素数据在 DEFINE过程中直接放入。
有没有开始有点不认识 FGL了?为了能跟对象体系有更好的整合,也保有传统 4GL兼容性,FourJs团队找出这样的方式进行对象化的操作。接下来还有更多的新变化,再请各位期待。