parameters - 关于如何正确转换变体记录函数参数的老式 Pascal 问题

标签 parameters casting pascal variant

我正在尝试使用允许内联转换或赋值的变体记录类型参数创建一个函数,如下所示:

type rectype = ( VT_INT, VT_CHAR, VT_BOOL );
     rec = record
       case t : rectype of
         VT_INT  : ( i : integer );
         VT_CHAR : ( c : char );
         VT_BOOL : ( b : boolean );
     end;

procedure handler( r : rec );
begin
  case r.t of
    VT_INT  : { do something with r.i }
    VT_CHAR : { do something with r.c }
    VT_BOOL : { do something with r.b }
  end;
end;

现在,上面的“工作”很好,只要您花时间手动设置变量,如下所示:
 r.t := VT_INT;
 r.i := 42;
 handler( r );

但是,我想稍微滥用一下打字系统,并尝试内联(我稍后会解释原因),大致如下:
 handler( rec( VT_INT, 42 ) );

辅助函数也可以,我尝试了几种不同的方法来做到这一点,可以在这里看到(为了简洁起见):

http://pastie.org/private/glxhwbpsbbh5gtxju0uvxa

现在,原因是:我正在研究,并且确实发布了一个单元测试套件,其目标是像 Pascal 本身一样可移植(在 FreePascal 和 Turbo Pascal 7 下构建(是的,真的))。我已经公开发布了开源软件(还不能链接,rep不够),其中包括针对不同类型的不同功能:isI()、isR()、isS()、isP()、isC()等。这重复了很多代码,我知道有更好的方法来做到这一点。我相信 FPC 和 Delphi 支持一种变体类型,我可以在这些平台上通过 IFDEF 指令使用它,但真正的关键是 TP7,出于淫秽的原因,我仍然想支持它。

每个函数调用 4 行来设置记录的原因实际上并不可行,因为这是面向用户的 API,并且进行复杂的测试意味着没有人会这样做。使用当前 API 的测试集很简单,只需一个函数调用即可执行每个测试,我只是希望可以将所有几个特定于类型的函数转换为以下内容:
is( VT_INT, SomeIntFunc( v ), 42, 'Test Name' );

我愿意竭尽全力避免在 TP7 下打字,包括自己在汇编中操作堆栈等。但我希望使用我不熟悉的语法的修改版本能够完成这项工作。

所以,老派的 Pascal 程序员(我知道肯定有一些),有什么建议吗?

最佳答案

Free Pascal 没有问题,因为它支持 Delphi 结构,如(自定义)变体、const 接口(interface)数组和其他处理运行时类型的技巧(只要它限制在可监督的数量内)。最近的 Delphi 和 FPC 支持泛型,你可能会用它复制“boost”很长的路要走。

然而,这样做是最困难的部分。它几乎没有无类型(或更好:运行时类型)功能。

我唯一能想到的是

 procedure rec(vartype:Ttypeofvar;var value):tvariantrecord;
 begin
   rec.t:=vartype
   case vartype of 
      vt_int: move (value,@rec.i,sizeof(integer));
      ..
      ..
 end;

一个可行的解决方法,但不是类型安全的,因为传递 rec(varint,"something double") 是可能的。除了 VAR 形式参数外,TP 没有太多可使用的。

在这一点上,您真的必须问自己,为 TP7 削弱您的框架是否真的值得。它已经死了16年了。让它安静地腐烂。

关于parameters - 关于如何正确转换变体记录函数参数的老式 Pascal 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3679373/

相关文章:

java - Python 中具有属性的枚举

spring-mvc - Spring MVC Redirect 显示 applicationinfo.properties 中的参数如何删除它们

c++ - 为什么 boost::call_traits<double>::param_type 是 "const double&"而不是 "double"

javascript - "characterIndex"的问题是什么,它给出了 Uncaught TypeError : Cannot read property '8' of undefined?

java - 为什么我无法从 Fragment 转换为 MyOwnFragment?

C# 跨不同程序集的转换

xml - 在 Delphi 中访问部分 XML 文档

C++:转换为不属于基类的接口(interface)

gcc - 使用 FreeRTOS 和 OpenOCD 配置 GCC

macos - Mac OS X 10 上 Pascal 中的退出代码 256