一、變體類型常用的函數介紹:
Variant: 一種可以擁有各種數據類型; 也可以告訴目前存儲的數據是什麼類型(通過使用VarType函數); 可以給相同的Variant分配不同的數據類型,只要Variant包含數字值就可以執行算法; variant數組只不過是variant型的數組,不必包含同類型的數據;
1、 VarArrayOf函數:更快捷的創建一維變體數組,可以創建全異的數值數組;
function VarArrayOf(const Values: array of Variant): Variant;
VarArrayOf是一種快速(寫代碼快而不是運行快)的方法生成一個一維Variant數據的方法,它接受一個Variant類型的Open Array,用這個數據生成一個一維的Variant Array of Variant(類型爲Variant)。由於Delphi對Open Array類型參數的支持,使你可以用一行語句生成一個數組。不過它有兩個缺陷:只能生成一維數組;只能生成元素類型是Variant的數組。使用Variant數組, 與使用標準Delphi數組類似;
例如: MyArray := VarArrayOf(['李維', 30, '60', 60.369, 'China']);
2、 VarArrayCreate函數:
function VarArrayCreate(const Bounds: array of Integer; VarType: TVarType): Variant;
Bounds: 告訴數組的上下界; VarType: 決定了數組的中存儲什麼類型的數據。其它的數組(如二維、或者其他類型等)只能用VarArrayCreate去創建,並用循環給元素賦值。
例如:創建數組的數組, 可以模仿任何類型的數據結構類型:
VarArrayX := VarArrayCreate([1,10], varVariant);
數組的單個元素可以裝載一個數組: VarArrayX[1] := VarArrayCreate([1,5], varVariant);
3、VarArrayHighBound、VarArrayLowBound函數:返回變體數組上/下限,從1開始(1:列;2:行;3:3維的最後一維)。
function VarArrayHighBound(const A: Variant; Dim: Integer): Integer;
4、VarArrayRedim函數:修改variant數組的最高限。
procedure VarArrayRedim(A: Variant; HighBound: Integer);
5、VarArrayDimCount函數:返回variant數組維數
unction VarArrayDimCount(const A: Variant): Integer;
6、VarArrayLock、VarArrayUnLock函數:避免運行時刻檢查。一般用於初始化一個大數組。
function VarArrayLock(const A: Variant): Pointer;
procedure VarArrayUnlock(var A: Variant);
在對Variant數組的每一個元素進行賦值時,都要通過運行時邏輯來檢查並判斷數據類型的兼容性、每個元素的位置等等。爲了避免運行時檢查,要用VarArrayLock()函數和VarArrayUnlock()過程。VarArrayLock()函數在內存中鎖定數組,使數組不再移動和改變大小,並能返回一個指向數組數據的指針。而VarArrayUnlock()過程用來對VarArrayLock()函數鎖定的數組進行解鎖,使數組能重新移動或改變大小。在鎖定數組後,能用更有效的方法對數組進行初始化。
7、VarArrayRef函數:獲得variant指向的數據
function VarArrayRef(const A: Variant): Variant;
8、VarIsArray函數:是一個簡單的布爾檢查函數,判斷是否是一個 Variant數組,是則返回True
function VarIsArray(const A: Variant): Boolean; overload;
function VarIsArray(const A: Variant; AResolveByRef: Boolean): Boolean; overload;
9、其他函數
1>、VarClear()過程清除Variant變量並將VType域的值設爲varEmpty.
2>、VarCopy()將Source複製到Dest。
3>、VarCast()將一個Variant轉換成指定的類型並存儲在另一個Variant變量中。
4>、VarType()返回指定Variant的varXXX類型代碼。
5>、VarAsType()跟VarCast()的功能一樣。
6>、VarIsEmpty()如果一個Variant變量的類型代碼是varEmpty則返回True。
7>、VarIsNull()判斷Variant變量是否包含null值。
8>、VarToStr()將一個Variant變量轉換成字符串表達式(如果Variant爲varEmpty或varNUll則爲空字符串)。
9>、VarFromDateTime()返回一個Variant變量,它存放着指定的TDateTime類型的值。
10>、VarToDateTime()返回在Variant中的TDateTime類型的值。
二、一個簡單實例代碼:
var
a, b: Variant;
I, J, K, M: Integer;
begin
//a是個一維Variant數組,元素類型是Variant,元素個數是3,上界是2,下界是0。
a := VarArrayOf([1234, 'abc ', Null]);
//b是一個16行4列的二維數組
b := VarArrayCreate[0, 3, 1, 16], varOleStr);
I := VarArrayHighBound(b, 1); // I是b的最大列號:3;
J := VarArrayLowBound(b, 1); // J是b的最小列號:0;
K := VarArrayHighBound(b, 2); // K是b的最大行號:16;
M := VarArrayLowBound(b, 2); // M是b的最小行號:1。
end;
注意,Variant數組下標是列在前,行在後,元素類型是PWideChar,最大列號是3,最小列號是0,最大行號是16,最小行號是1。
三、變體類型和流的相互轉換
//1、 變體類型轉成流
procedure VariantToStream(const Data: OleVariant; Stream: TStream);
var
p: Pointer;
begin
p := VarArrayLock(Data); // 加鎖,並返回一個指針指向的數據。 避免運行時時刻檢查
try
Stream.Write(p^, VarArrayHighBound(Data,1) + 1); // 返回最大的列號
finally
VarArrayUnlock(Data); // 解鎖,使數組能重新移動或改變大小。
end;
end;
// 2、流轉成變體類型
function StreamToVariant(Stream: TStream): OleVariant;
var
p: Pointer;
begin
Result := VarArrayCreate([0, Stream.Size - 1], varByte);// 創建一個以爲的數組。類型爲varByte
p := VarArrayLock(Result);
try
Stream.Position := 0; // 設置流的位置
Stream.Read(p^, Stream.Size);
finally
VarArrayUnlock(Result);
end;
end;