[英]How to share records structure between projects, with slight variations?
我有2個處理相同數據,不同流程的項目。 主數組幾乎相同,只是略有不同,例如:
// Project 1
TData1 = record
A:string;
B:integer;
C:word;
...
end;
// Project 2
TData1 = record
A:string;
B:integer;
C:word;
...
XMLNode:TXMLNode; // Extra value needed in Project 2, not needed in Project 1
end;
我想在項目之間共享許多數組。 我想保持相同的數組結構,以便我可以復制並粘貼需要在兩個項目中實現的任何將來的更改。 有什么辦法可以使記錄保持相同但略有不同?
我在想這樣的事情:
// in Project 1:
TExtras = record
end;
// in Project 2:
TExtras = record
XMLNode:TXMLNode;
end;
// shared - in both projects
TData1 = record
A:string;
B:integer;
C:word;
...
Extras:TExtras; // different extra fields based on project needs
end;
而且我可以將其他字段添加到Project2的Extras中,以使用Data1.Extras.XMLNode
訪問字段。 不確定這是否可以用於將來。
目標是一天之內將所有共享結構放入一個共享單元中,一個維護點,而不再需要復制和粘貼。 我需要數組來保持靈活性,就像簡單的數組( array of TData1
或TArray<TData1>
array of TData1
)一樣,所以我不能進入復雜的實現方式,這將限制選項來輕松地復制,排序,區分,操縱數據...
那是正確的方法嗎? 還有更好的主意嗎?
編輯:
兩個項目都使用相同的數據,因此它們都從相同的“源”文件中讀取,但是產生不同的最終結果。 現在,我有很多數組,其中有99%的數組用於兩個項目中的相同目的,相同功能。 但是現在,當我處理一個或另一個項目時,添加新的記錄字段,使用新字段的新功能,並且如果我不立即同步結構和新功能,那么可能會在幾周后發生在項目2中執行相同的操作,我將創建具有不同名稱和不同函數名稱的新字段。 因此,當我最終在項目之間復制某些復雜功能時,我發現它們僅由於命名不同而無法匹配。
編輯2:
從所有評論和建議中,我決定走另一條路:在共享單元中共享通用數據結構和代碼,並在項目2中創建帶有額外記錄字段的其他數組。我將創建這些新數組,這些新數組鏈接到主數據數組,從而有:
// shared data
TData1 = record
A:string;
B:integer;
C:word;
...
end;
Data1:TArray<TData1>;
// additional in Project 2
TDataExtra = record
DataIdx:integer;// link to TData1
XMLNode:TXMLNode;
...
end;
DataExtras:TArray<TDataExtra>;
可以輕松訪問每個Data1記錄的XMLNode值:
fGetXMLNode(i); // where i is index in Data1 array and function will return XMLNode
我相信,我可以保留共享單元,並以最少的額外工作將任何額外的內容添加到任何陣列,這仍然比維護2個數據結構和代碼的成本低。
那會是更好的解決方案嗎?
如果沒有完整的上下文,很難說哪種解決方案是最佳/更好,但是這里有一些其他方法可以達到相同的效果。
條件定義
TData1 = record
A:string;
B:integer;
C:word;
[...]
{$IFDEF NEEDXMLNODEINTDATA1}
XMLNode:TXMLNode; // different extra fields based on project needs
{$ENDIF}
end;
使用新結構
在第二個應用程序中使用其他結構。 我希望這是大多數情況下的正確方法。
TData1Node = record
Data1 : TData1;
XMLNode : TXMLNode;
end;
一直包含XMLNode
由於它只是一個指針,除非您的應用程序中有大量的記錄,否則它幾乎不會注冊內存使用情況。
Pascal沒有void / Unit數據類型,您仍然可以進行模擬。 編譯器並不總是對此感到SizeOf(someType)
,在某些路徑中,它只是不做任何假設/檢查,在某些極端情況下SizeOf(someType)
可能為零。
不過,如果您確實需要壓縮Project 2中的每個最后一個字節,同時保持與Project 1共享源,則可以使用此丑陋的技巧:
文件Project_1.inc
{$IFnDEF THIS_IS_PROJECT_1}
halt compilation! wrong setup!!!
{$EndIf}
{$IFDEF THIS_IS_PROJECT_2}
halt compilation! wrong setup!!!
{$EndIf}
type TDataPayload = TXMLNode;
文件Project_2.inc
{$IFnDEF THIS_IS_PROJECT_2}
halt compilation! wrong setup!!!
{$EndIf}
{$IFDEF THIS_IS_PROJECT_1}
halt compilation! wrong setup!!!
{$EndIf}
type REmpty = packed record end;
type TDataPayload = REmpty;
// after compilation - call `assert(SizeOf(TDataPayload) = 0);`
文件CommonDataType.pas
{$IfDef THIS_IS_PROJECT_1}
{$INCLUDE Project_1.inc}
{$EndIf}
{$IfDef THIS_IS_PROJECT_2}
{$INCLUDE Project_2.inc}
{$EndIf}
TData1 =
{$IFDEF THIS_IS_PROJECT_2}
packed
{$EndIf}
record
A:string;
B:integer;
C:word;
...
Payload: TDataPayLoad;
end;
話雖這么說,您的評估表明您不能通過項目2中的type TXMLNode=byte
兼容性存根type TXMLNode=byte
浪費單個字節,這對我來說似乎非常可疑。 因為:
record
而不是慢速字節壓縮packed record
A:string;
每個記錄中的每個指針花費4(或8)個字節,然后作為StringRec
標頭再使用12個字節,然后在字符串內容之后再分配未知的預分配大小寫緩沖區,然后為尾隨#0增加兩個額外的字節,以及然后在堆管理器中支持數據結構。 仍然只有一個type TXMLNode=boolean
stub type TXMLNode=boolean
額外字節太多了??? 簡便的解決方案是保持兩個項目之間共享數據結構和相關功能,並添加包含每個項目特定數據的附加數組。 使用額外的數組將帶來更多的工作,但是將使共享的代碼真正共享。
因此,代替其他答案中提出的新類或IFDefs,鏈接到主數據的簡單額外數組是解決該問題的最佳選擇:
// shared main data through both projects
TData1 = record
A:string;
B:integer;
C:word;
...
end;
Data1:TArray<TData1>;
// additional in Project 2
TDataExtra = record
DataIdx:integer;// link to TData1
XMLNode:TXMLNode;
...
end;
DataExtras:TArray<TDataExtra>;
使用此解決方案,可以輕松添加,擴展任何其他數組,例如DataExtras或其他數組的其他字段,而無需更改共享代碼。 共享代碼將易於維護,因為它僅包含主要數據,而沒有僅針對一個項目的特定內容
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.