傳遞一個序號參數
回答
你需要使用一個untyped parameter:
procedure Foo(const ordinal);
或
procedure Foo(var ordinal);
當然,你在某種程度上,你可以做什麼限制在這樣的例程裏面,因爲你已經放棄了類型系統。
序號的大小是否保證爲4字節? – 2011-04-04 15:38:02
不,它不是... – 2011-04-04 15:38:41
那麼,現在你可以將*任何*傳遞給這些程序,而不僅僅是序號。所以這不是'inc'等工作原理。 (的確,代碼洞察力認爲'inc'的參數是'var X:ordinal',但是這種行爲你不能在你自己的proc/func中獲得,我想。) – 2011-04-04 15:38:54
找到了一種可能的方式,可能不是你所期望的,但嘿,我找到了一種方法!使用Variants
。將無類型參數傳遞給一個過程的問題是你得到一個普通的指針,沒有類型信息,所以你不能對它做任何有用的事情。字節是1個字節,多達256個元素的枚舉是1個字節字節,最多2^16個元素的枚舉是2個字節,整數是4個字節(除非它們是8)。但有一種類型允許傳遞任何東西,並關心足夠的類型信息以使事情發揮作用:Variant
。我故意在Delphi 7中寫了下面的例子,以確保我不會意外地使用任何Delphi 2010或Delphi XE的善良。
編輯:更新了代碼示例來處理一個被認爲序號由Variants.VarTypeIsOrdinal
任何類型。包括所有整數類型+布爾值。顯然Enum被視爲Byte,所以它也吞下了。
program Project1;
{$APPTYPE CONSOLE}
uses
ExceptionLog,
SysUtils, Variants;
type TSomeEnum = (e0, e1, e2, e3, e4);
procedure DoSomethingWithEnum(V: Variant);
var i: Integer;
b: Byte;
lw: LongWord; // Cardinal!
i64: Integer;
begin
case VarType(V) of
varInt64:
begin
i64 := V;
WriteLn(i64);
end;
varSmallint, varInteger, varShortInt:
begin
i := V;
WriteLn(i);
end;
varByte:
begin
b := V;
WriteLn(b);
end;
varWord, varLongWord:
begin
lw := V;
WriteLn(lw);
end;
varBoolean:
begin
if V then WriteLn('True') else WriteLn('False');
end;
else WriteLn('NOT a variant type (type = #' + IntToStr(Ord(VarType(V))));
end;
end;
var i: Integer;
b: Byte;
c: Cardinal;
enum: TSomeEnum;
w: Word;
si: Shortint;
begin
i := 1;
b := 2;
c := 3;
enum := e4;
w := 5;
si := -6;
DoSomethingWithEnum(i);
DoSomethingWithEnum(b);
DoSomethingWithEnum(c);
DoSomethingWithEnum(enum);
DoSomethingWithEnum(True);
DoSomethingWithEnum(w);
DoSomethingWithEnum(si);
Readln;
end.
運行時變體的性能還有很多不足之處。 – 2011-04-04 17:41:24
@Warren,Variants可能不如我們希望的那麼快,但它們也不那麼慢。 – 2011-04-04 18:25:55
之所以這樣做是困難的是,公司(X),DEC(x)和其他類似強的鬆(x)和SUCC(x)的實際,由編譯器生成,並且,如果你就像函數式的語法糖超過固有的編譯器操作一樣。
你可以像一些人建議的那樣,通過重載來做一些這樣的事情,其中一些是巧妙地使用泛型,另一些則使用泛型。但是對於模擬這些功能來說沒有什麼方便,或者功能上完全一樣。
例如,對於所有有序類型(包括Enums,Integers和這些類型的子範圍),編譯器都實現了Inc()(經典「Wirth」Pascal的一個現在頗爲模糊的功能是,所有類型都可以在這些類型上定義子範圍類型)。
如果您實際上告訴了我們更多關於您正在做的事的信息,可能會更加接近。但是一般的答案是,不,甚至沒有Inc和Dec的源代碼,因爲這些是編譯器原語。如果有功能Inc的RTL源代碼,你可以看看它,並適應它。 (x)可以定義爲x:= Succ(x),但是,那麼如何定義Succ(x)?由於x:= Inc(x)?你看。在某個時候,編譯器「魔術師」接管了。
- 1. 傳遞參數給一個由符號
- 2. 傳遞「=」號作爲參數傳遞給一個bat文件
- 3. NSURL傳遞一個參數
- 4. 傳遞參數/參數信號在C
- 5. 如何將一個參數傳遞給信號中的函數?
- 6. 如何查找像參數一樣傳遞的最大序號?
- 7. 傳遞函數作爲參數傳遞給另一個函數
- 8. 傳遞多個參數與一個radio_button_tag
- 9. 傳遞一個函數的參數
- 10. 參數傳遞給另一個函數
- 11. 參數傳遞給另一個函數
- 12. 作爲參數傳遞一個函數?
- 13. 傳遞一個帶參數的函數
- 14. 傳遞一個數組作爲參數
- 15. 傳遞20+參數到一個函數
- 16. 傳遞一個類,函數參數
- 17. 傳遞一個向量函數參數
- 18. Boost :: signals2 - 傳遞一個信號槽作爲參數
- 19. 如何成參數傳遞給一個信號
- 20. 多個參數傳遞到一個單一的參數
- 21. 在pthread_create:傳遞一個參數作爲最後一個參數
- 22. 傳遞函數的參數作爲參數傳遞給另一個函數
- 23. 傳遞一個類/結構vs傳遞幾個參數
- 24. 傳遞這個作爲參數傳遞給一個angularjs功能
- 25. 傳遞一個指針作爲參數傳遞給函數
- 26. 調用程序或者函數傳遞一個數值參數
- 27. 在一個函數中傳遞一個參數在另一個函數中被「參考」傳遞
- 28. 傳遞一個在多個參數的函數參數在JavaScript
- 29. 將參數傳遞給一個封閉
- 30. 將參數傳遞給另一個類
你想做什麼?不是簡單的重載方法的解決方案? – 2011-04-04 15:41:57
重載的方法我需要爲每個我想使用的枚舉編寫一個新的方法。 – 2011-04-04 15:47:55
@JamesB,那麼?你的問題是否可以編寫一個採用任何序數的函數。重載是一種有效的方式。 David的答案是最接近Inc()或High()的。你沒有在你的問題中的任何地方說過你的函數會做什麼,或者在參數中會收到什麼樣的序數。即使枚舉是「技術上」序數,它們也會被更恰當地描述爲「數組」(概念和實現)。此外,枚舉的大小是可變的(8到256位),這使得編寫泛型方法變得更加困難。 – 2011-04-05 07:02:47