RTNPARM 关键字和用例示例

Example for RTNPARM keyword and use case

在阅读了有关 RTNPARM 关键字的 IBM 文档后,我仍然不清楚如何处理它。
有人可以给我一个小程序示例吗?

如果它快得多,为什么 IBM 没有将其隐式化?

你不需要"have to handle it",这就是它的美妙之处。

 D TestProc1       Pr         32000a

 D TestProcV7      Pr         32000a    RTNPARM

myResults = TestProc1();
myResults = TesProcV7();

无论是否指定 RTNPARM,对过程的调用都采用相同的编码。

它不是默认值(即隐式),因为它是在 v7 中添加的。此外,只有当返回值大于 16 个字节时才会更快。

另外,如果被调用过程有可选参数,您必须在被调用过程中以不同方式处理它们。

给出

 D MyProc          PI                  LikeDS(myResult)
 D  Compulsory                   20a
 D  Optional                     10a   Options(*NoPass)

旧方法:

   If %Parms > 1; 
      DoStuff();
   EndIf;

新方式

   If %ParmNum(Optional) <= %Parms; 
      DoStuff();
   EndIf;

以上来自 Large Subprocedure Return Values: V7 Brings Relief

的更多详细信息和示例

RTNPARM 适用于 return 一个非常长的字符值,通常只部分使用的过程。 return 值被压入堆栈,与 10 字节字符相比,将 64K 字符压入堆栈需要更长的时间。通过引用传递的参数只在堆栈上放置一个指针。当您使用 RTNPARM 关键字时,它会将 return 值视为按引用传递的参数。在内部,第一个参数成为通过引用传递的 return 值。您仍然以与通常相同的方式传递和检索 return 值,但是如果您想使用 %parms() 获取参数数量,则参数数量将递增 1。 IBM 引入了 %parmnum() 内置来处理这个问题。

所以这是一个简单的例子:

   dcl-proc sample;
     dcl-pi *n Varchar(65535) RtnParm;
       parm1   VarChar(256) const options(*nopass);
     end-pi;

     dcl-s result         Varchar(65535) Inz('');
     dcl-s str1           Varchar(256) Inz('');

     if %parms() >= %parmnum(parm1);
       str1 = parm1;
     endif;

     // do some stuff

     return result;
   end-proc;

RTNPARM 不能隐含的另一个原因是它是一个纯粹的角色扮演游戏。如果该过程是用另一种编程语言编写的或从另一种语言调用的,则不能使用 RTNPARM,因为另一种语言会假定正在使用正常的 return-value 机制。

如果将子过程与 Microsoft VB/VBA 进行比较,带有 rtnparm 的子过程是函数,没有 rtnparm 的子过程是子过程。