C的動(dòng)態(tài)類型檢查
這次美國(guó)之行的一大收獲就是終于正視了Objective-C而不再只是當(dāng)它是不順手的工具了。這主要是有機(jī)會(huì)拜讀了Brad Cox的《Objective-Oriented Programming, an evolutionary approach》。今天就談?wù)勊?1頁(yè)提到的那個(gè)極少C程序員甚至C編譯器作者知道的一個(gè)極為餛飩的語(yǔ)法:
- struct MYSTRUCT someVariables;
- someVariable = (*((struct MYSTRUCT *)(*)() _msg))(someObject, …);
C語(yǔ)言是靜態(tài)類型檢查的編譯語(yǔ)言.例如下面程序定義和使用了兩個(gè)類型:浮點(diǎn)和定點(diǎn)。
- #include <stdio.h>
- typedef struct {
- float x, y;
- } FloatingPoint;
- typedef struct {
- int x, y;
- int scale;
- } FixedPoint;
- int main() {
- FloatingPoint flo;
- FixedPoint fix;
- printf("(%f,%f)\n", flo.x, flo.y);
- printf("(%f, %f)\n", 1.0*fix.x/fix.scale, 1.0*fix.y/fix.scale);
- }
不同類型間的轉(zhuǎn)換需要cast,否則編譯時(shí)會(huì)被警告。后門還是有的,就是void *類型。我們聲明id是此void *類型,加入一個(gè)使用它的迷你函數(shù):
- typedef void *id;
- id thePoint(id thePoint) {
- return thePoint;
- }
這樣在main里我們可以使用明確的類型轉(zhuǎn)換,不會(huì)被警告:
- id flid = thePoint(&flo);
- printf("(%f,%f)\n", ((FloatingPoint *)flid)->x, ((FloatingPoint *)flid)->y);
但類型錯(cuò)了也沒(méi)了警示報(bào)告:
- FloatingPoint *flip = thePoint(&fix);
- printf("(%f,%f)\n", flip->x, flip->y);
我們?cè)囍膶憺殚g接的函數(shù)指針類型,當(dāng)然也沒(méi)有編譯預(yù)警:
- id (*thePointPointer)(id);
- thePointPointer = &thePoint;
- flip = thePointPointer(&fix);
- printf("(%f,%f)\n", flip->x, flip->y);
但如果我們加入明確類型,就會(huì)看到預(yù)期的警示,雖然是有些啰嗦:
- FloatingPoint *(*theFloatingPointPointer)(FloatingPoint *);
- theFloatingPointPointer = &thePoint;
- flip = theFloatingPointPointer(&fix);
- printf("(%f,%f)\n", flip->x, flip->y);
但這很容易解決,寫在一行就行了:
- FloatingPoint *flop = ((FloatingPoint *(*)(FloatingPoint *))&thePoint)(&fix);
我想這就是書中提到的意思。Objective-C是超級(jí)的C語(yǔ)言,這些餛飩都被精心的包裝成了簡(jiǎn)潔的語(yǔ)法。帶類型檢查的動(dòng)態(tài)語(yǔ)言 —— 我喜歡。























