• Pascal 两个异构记录的赋值!


    前几天看到一个帖子,讨论两个记录复制,贴主提出了一个解决方案,但是不想用,希望大家集思广益,让人没想到的是方法还真的挺多,这里罗列一下。

    这是需要复制的的两种记录

    TypeA = record
      value1 : word;
      value2 : word;
      value3 : word;
      end;
    
    TypeB = record
      b1 : byte;
      b2 : byte;    
      end;

    方案1:贴主抛的砖1

    CopyMemory(@TypeA, @TypeB, Length(TypeB))

    方案2:贴主抛的砖2

    TypeB.b1 := TypeA.value1 && $FF;

    方案3.0:用变体记录

    ..
    TypeAB = packed record
      case boolean of
        false:(a:TypeA);
        true:(b:TypeB);
    end;
    ..
    

    方案3.1:用变体记录是低级形式,需要调整记录的定义形式,否则会由于系统不同上面的结构会产生不同的情况(确实存在BUG)。

    type
      TTwoBytes : packed record
        ByteA, ByteB : Byte;
      end;
    
      TValueRecord : packed record:
        case Boolean of
          True: (Value: SmallInt);
          False: (ValueBytes : TTwoBytes);
        end;
      end;
    
      TMyRecord = packed record
        Value1, Value2, Value3 : TValueRecord;
      end;
    
    ....
    
    var
      MyRecord: TMyRecord;
      MyBytes: TTwoBytes;
    begin
      MyRecord := ...; // Fill it with data here
      // Access the words / smallints by something like: MyRecord.Value1.Value
      MyBytes := MyRecord.ValueBytes; // The key bit: type safe assignment
      // Do something with MyBytes.ByteA or MyBytes.ByteB
    end;

    方案4:利用pascal自带的 Move

    procedure CopyAtoB( const A: TypeA; var B: TypeB);
    begin
    // Assume A is bigger than B.
    Move( A, B, SizeOf( TypeB))
    end;
    
    //or (with Math unit)
    
    procedure CopyAtoB( const A: TypeA; var B: TypeB);
    begin
    // No assumptions about A, B sizes.
    FillChar( B, SizeOf( B), 0);
    Move( A, B, Min( SizeOf( TypeA), SizeOf( TypeB)))
    end;

    方案5:利用操作符重载

    type
        TTypeA = record
          value1 : integer;
          value2 : integer;
          value3 : integer;
        end;
    
        TTypeB = record
          b1 : byte;
          b2 : byte;
          class operator Implicit(value : TTypeA):TTypeB;
        end;
    
    class operator TTypeB.Implicit(value: TTypeA): TTypeB;
    begin
        result.b1 := Hi(value.value1);
        result.b2 := Lo(value.value1);
    end;
    
    
    var a : TTypeA;
        b : TTypeB;
    begin
        b := a;
    end.

    方案6:利用字节流复制

    var a : TTypeA;
        bs : TBytesStream;
        bArr : TArray<byte>;//array of byte;
    begin
        bs := TBytesStream.Create();
        bs.Write(a, sizeof(a));
        bArr := bs.Bytes;
    end;

    方案6:CopyMemory() (Windows unit)

    type
      PTypeA = ^TTypeA;
      TTypeA = record
        value1 : word;
        value2 : word;
        value3 : word;
      end;
      PTypeB = ^TTypeB;
      TTypeB = record
        b1 : byte;
        b2 : byte;
      end;
    var
      A: TTypeA = (value1 : 11; value2 : 22; value3 : 33);
      B: TTypeB;
      B1: TTypeB;
      C: {packed?} array of Byte;
    begin
      Assert(SizeOf(TTypeA) >= SizeOf(TTypeB));
      //...
      B:= PTypeB(@A)^;
      //...
      SetLength(C, SizeOf(A));
      // TTypeA record to Byte Array
      PTypeA(@C[0])^:= A;
      // Byte Array to TTypeB
      B1:= PTypeB(@C[0])^
    end;

  • 相关阅读:
    cocos2d JS 在 JavaScript 中,怎样把一个对象转化成 JSON 字符串?
    cocos2d-x 暂停/恢复 与场景相关(SceneGraph类型)的监听器
    cocos2d CCNode类(节点属性大全)
    cocos2d-x 错误异常抛出捕获和崩溃拦截
    cocos2d JS 鼠标响应事件
    cocos2d JS 创建实现换行功能的聊天文本 testLable
    cocos2d JS 自定义事件分发器(接收与传递数据) eventManager
    cocos2d JS 监听键盘触摸响应事件(cc.EventListener.KEYBOARD)
    cocos2d JS touch(触摸监听)-快速添加事件监听器到管理器
    cocos2dx C++ imageView(图片/九宫格)相关属性大全
  • 原文地址:https://www.cnblogs.com/hieroly/p/12334214.html
Copyright © 2020-2023  润新知