深度解密Go语言之关于 interface 的 10 个问题
è¿æ¬¡æç« ä¾ç¶å¾é¿ï¼åºæ¬ä¸æ¶µçäºÂ interface
çæ¹æ¹é¢é¢ï¼æä¾åï¼ææºç åæï¼ææ±ç¼åæï¼åååååäº 20 å¤å¤©ãæ´æ´æ´æ´ï¼é¿ç¯å¤§è®ºï¼ä¾ç¶æäºä¸è¥¿æ²¡ææ¶åå°ï¼æ¯å¦æç« éæ²¡æåå°åå°
ï¼å½ç¶ï¼åé¢ä¼åç¬åä¸ç¯å
³äºåå°
çæç« ï¼è¿æ¯åè¯ã
è¿æ¯å¸æçä½ å¨çå®æç« åè½æææ¶è·ï¼æä»»ä½é®é¢ææè§å»ºè®®ï¼æ¬¢è¿å¨æç« åé¢çè¨ã
è¿ç¯æç« çæ¶ææ¯è¾ç®åï¼ç´æ¥æåº 10 个é®é¢ï¼ä¸ä¸è§£çã
1. Go è¯è¨ä¸é¸åç±»åçå ³ç³»
å ç´æ¥æ¥çç»´åºç¾ç§éçå®ä¹ï¼
If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
ç¿»è¯è¿æ¥å°±æ¯ï¼å¦ææä¸ªä¸è¥¿é¿å¾åé¸åï¼åé¸å䏿 ·æ¸¸æ³³ï¼åé¸å䏿 ·ååå«ï¼é£å®å°±å¯ä»¥è¢«çææ¯ä¸åªé¸åã
Duck Typing
ï¼é¸åç±»åï¼æ¯å¨æç¼ç¨è¯è¨çä¸ç§å¯¹è±¡æ¨æçç¥ï¼å®æ´å
³æ³¨å¯¹è±¡è½å¦ä½è¢«ä½¿ç¨ï¼è䏿¯å¯¹è±¡çç±»åæ¬èº«ãGo è¯è¨ä½ä¸ºä¸é¨éæè¯è¨ï¼å®éè¿éè¿æ¥å£çæ¹å¼å®ç¾æ¯æé¸åç±»åã
ä¾å¦ï¼å¨å¨æè¯è¨ python ä¸ï¼å®ä¹ä¸ä¸ªè¿æ ·ç彿°ï¼
å½è°ç¨æ¤å½æ°çæ¶åï¼å¯ä»¥ä¼ å
¥ä»»æç±»åï¼åªè¦å®å®ç°äºÂ say_hello()
彿°å°±å¯ä»¥ãå¦ææ²¡æå®ç°ï¼è¿è¡è¿ç¨ä¸ä¼åºç°é误ã
èå¨éæè¯è¨å¦ Java, C++ ä¸ï¼å¿
é¡»è¦æ¾ç¤ºå°å£°æå®ç°äºæä¸ªæ¥å£ï¼ä¹åï¼æè½ç¨å¨ä»»ä½éè¦è¿ä¸ªæ¥å£çå°æ¹ãå¦æä½ å¨ç¨åºä¸è°ç¨ hello_world
Â å½æ°ï¼å´ä¼ å
¥äºä¸ä¸ªæ ¹æ¬å°±æ²¡æå®ç°Â say_hello()
çç±»åï¼é£å¨ç¼è¯é¶æ®µå°±ä¸ä¼éè¿ãè¿ä¹æ¯éæè¯è¨æ¯å¨æè¯è¨æ´å®å
¨çåå ã
卿è¯è¨åéæè¯è¨çå·®å«å¨æ¤å°±ææä½ç°ãéæè¯è¨å¨ç¼è¯æé´å°±è½åç°ç±»åä¸å¹é
çé误ï¼ä¸å卿è¯è¨ï¼å¿
é¡»è¦è¿è¡å°é£ä¸è¡ä»£ç æä¼æ¥éãæä¸å¥ï¼è¿ä¹æ¯æä¸åæ¬¢ç¨ python
çä¸ä¸ªåå ãå½ç¶ï¼éæè¯è¨è¦æ±ç¨åºåå¨ç¼ç é¶æ®µå°±è¦æç
§è§å®æ¥ç¼åç¨åºï¼ä¸ºæ¯ä¸ªåéè§å®æ°æ®ç±»åï¼è¿å¨æç§ç¨åº¦ä¸ï¼å 大äºå·¥ä½éï¼ä¹å é¿äºä»£ç éã卿è¯è¨å没æè¿äºè¦æ±ï¼å¯ä»¥è®©äººæ´ä¸æ³¨å¨ä¸å¡ä¸ï¼ä»£ç 乿´çï¼åèµ·æ¥æ´å¿«ï¼è¿ä¸ç¹ï¼å python çå妿¯è¾æ¸
æ¥ã
Go è¯è¨ä½ä¸ºä¸é¨ç°ä»£éæè¯è¨ï¼æ¯æååä¼å¿çãå®å¼å ¥äºå¨æè¯è¨ç便å©ï¼åæ¶åä¼è¿è¡éæè¯è¨çç±»åæ£æ¥ï¼åèµ·æ¥æ¯é常 Happy çãGo éç¨äºæä¸çåæ³ï¼ä¸è¦æ±ç±»åæ¾ç¤ºå°å£°æå®ç°äºæä¸ªæ¥å£ï¼åªè¦å®ç°äºç¸å ³çæ¹æ³å³å¯ï¼ç¼è¯å¨å°±è½æ£æµå°ã
æ¥ç个ä¾åï¼
å å®ä¹ä¸ä¸ªæ¥å£ï¼åä½¿ç¨æ¤æ¥å£ä½ä¸ºåæ°ç彿°ï¼
â忥å®ä¹ä¸¤ä¸ªç»æä½ï¼
æåï¼å¨ main 彿°éè°ç¨ sayHello() 彿°ï¼
ç¨åºè¾åºï¼
å¨ main 彿°ä¸ï¼è°ç¨è°ç¨ sayHello() 彿°æ¶ï¼ä¼ å
¥äºÂ golang, php
对象ï¼å®ä»¬å¹¶æ²¡ææ¾å¼å°å£°æå®ç°äº IGreeting ç±»åï¼åªæ¯å®ç°äºæ¥å£æè§å®ç sayHello() 彿°ãå®é
ä¸ï¼ç¼è¯å¨å¨è°ç¨ sayHello() 彿°æ¶ï¼ä¼éå¼å°å° golang, php
å¯¹è±¡è½¬æ¢æ IGreeting ç±»åï¼è¿ä¹æ¯éæè¯è¨çç±»åæ£æ¥åè½ã
顺带åæä¸ä¸å¨æè¯è¨çç¹ç¹ï¼
åéç»å®çç±»åæ¯ä¸ç¡®å®çï¼å¨è¿è¡æé´æè½ç¡®å® 彿°åæ¹æ³å¯ä»¥æ¥æ¶ä»»ä½ç±»åçåæ°ï¼ä¸è°ç¨æ¶ä¸æ£æ¥åæ°ç±»å ä¸éè¦å®ç°æ¥å£
æ»ç»ä¸ä¸ï¼é¸åç±»åæ¯ä¸ç§å¨æè¯è¨ç飿 ¼ï¼å¨è¿ç§é£æ ¼ä¸ï¼ä¸ä¸ªå¯¹è±¡ææçè¯ä¹ï¼ä¸æ¯ç±ç»§æ¿èªç¹å®çç±»æå®ç°ç¹å®çæ¥å£ï¼èæ¯ç±å®"å½åæ¹æ³å屿§çéå"å³å®ãGo ä½ä¸ºä¸ç§éæè¯è¨ï¼éè¿æ¥å£å®ç°äº é¸åç±»å
ï¼å®é
䏿¯ Go çç¼è¯å¨å¨å
¶ä¸ä½äºéå¿ç转æ¢å·¥ä½ã
2. 弿¥æ¶è åæéæ¥æ¶è çåºå«
æ¹æ³
æ¹æ³è½ç»ç¨æ·èªå®ä¹çç±»åæ·»å æ°çè¡ä¸ºãå®å彿°çåºå«å¨äºæ¹æ³æä¸ä¸ªæ¥æ¶è
ï¼ç»ä¸ä¸ªå½æ°æ·»å ä¸ä¸ªæ¥æ¶è
ï¼é£ä¹å®å°±åæäºæ¹æ³ãæ¥æ¶è
å¯ä»¥æ¯å¼æ¥æ¶è
ï¼ä¹å¯ä»¥æ¯æéæ¥æ¶è
ã
å¨è°ç¨æ¹æ³çæ¶åï¼å¼ç±»åæ¢å¯ä»¥è°ç¨å¼æ¥æ¶è
çæ¹æ³ï¼ä¹å¯ä»¥è°ç¨æéæ¥æ¶è
çæ¹æ³ï¼æéç±»åæ¢å¯ä»¥è°ç¨æéæ¥æ¶è
çæ¹æ³ï¼ä¹å¯ä»¥è°ç¨å¼æ¥æ¶è
çæ¹æ³ã
ä¹å°±æ¯è¯´ï¼ä¸ç®¡æ¹æ³çæ¥æ¶è æ¯ä»ä¹ç±»åï¼è¯¥ç±»åçå¼åæéé½å¯ä»¥è°ç¨ï¼ä¸å¿ ä¸¥æ ¼ç¬¦åæ¥æ¶è çç±»åã
æ¥ç个ä¾åï¼
ä¸ä¾åçè¾åºç»ææ¯ï¼
è°ç¨äºÂ growUp
Â å½æ°åï¼ä¸ç®¡è°ç¨è
æ¯å¼ç±»åè¿æ¯æéç±»åï¼å®ç Age
å¼é½æ¹åäºã
å®é ä¸ï¼å½ç±»ååæ¹æ³çæ¥æ¶è ç±»åä¸åæ¶ï¼å ¶å®æ¯ç¼è¯å¨å¨èååäºä¸äºå·¥ä½ï¼ç¨ä¸ä¸ªè¡¨æ ¼æ¥åç°ï¼
- |
弿¥æ¶è |
æéæ¥æ¶è |
å¼ç±»åè°ç¨è |
æ¹æ³ä¼ä½¿ç¨è°ç¨è çä¸ä¸ªå¯æ¬ï¼ç±»ä¼¼äºâä¼ å¼â |
使ç¨å¼çå¼ç¨æ¥è°ç¨æ¹æ³ï¼ä¸ä¾ä¸ï¼ |
æéç±»åè°ç¨è |
æé被解å¼ç¨ä¸ºå¼ï¼ä¸ä¾ä¸ï¼ |
å®é ä¸ä¹æ¯âä¼ å¼âï¼æ¹æ³éçæä½ä¼å½±åå°è°ç¨è ï¼ç±»ä¼¼äºæéä¼ åï¼æ·è´äºä¸ä»½æé |
弿¥æ¶è åæéæ¥æ¶è
åé¢è¯´è¿ï¼ä¸ç®¡æ¥æ¶è ç±»åæ¯å¼ç±»åè¿æ¯æéç±»åï¼é½å¯ä»¥éè¿å¼ç±»åææéç±»åè°ç¨ï¼è¿éé¢å®é ä¸éè¿è¯æ³ç³èµ·ä½ç¨çã
å 说ç»è®ºï¼å®ç°äºæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ï¼ç¸å½äºèªå¨å®ç°äºæ¥æ¶è æ¯æéç±»åçæ¹æ³ï¼èå®ç°äºæ¥æ¶è æ¯æéç±»åçæ¹æ³ï¼ä¸ä¼èªå¨çæå¯¹åºæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ã
æ¥çä¸ä¸ªä¾åï¼å°±ä¼å®å ¨æç½ï¼
ä¸è¿°ä»£ç éå®ä¹äºä¸ä¸ªæ¥å£Â coder
ï¼æ¥å£å®ä¹äºä¸¤ä¸ªå½æ°ï¼
æ¥çå®ä¹äºä¸ä¸ªç»æä½Â Gopher
ï¼å®å®ç°äºä¸¤ä¸ªæ¹æ³ï¼ä¸ä¸ªå¼æ¥æ¶è
ï¼ä¸ä¸ªæéæ¥æ¶è
ã
æåï¼æä»¬å¨Â main
彿°ééè¿æ¥å£ç±»åçåéè°ç¨äºå®ä¹çä¸¤ä¸ªå½æ°ã
è¿è¡ä¸ä¸ï¼ç»æï¼
使¯å¦ææä»¬æÂ main
彿°çç¬¬ä¸æ¡è¯å¥æ¢ä¸ä¸ï¼
è¿è¡ä¸ä¸ï¼æ¥éï¼
çåºè¿ä¸¤å¤ä»£ç çå·®å«äºåï¼ç¬¬ä¸æ¬¡æ¯å° &Gopher
 èµç»äºÂ coder
ï¼ç¬¬äºæ¬¡åæ¯å° Gopher
 èµç»äºÂ coder
ã
ç¬¬äºæ¬¡æ¥éæ¯è¯´ï¼Gopher
 没æå®ç°Â coder
ã徿æ¾äºå§ï¼å 为 Gopher
 类å并没æå®ç°Â debug
æ¹æ³ï¼è¡¨é¢ä¸çï¼ *Gopher
 类å乿²¡æå®ç°Â code
Â æ¹æ³ï¼ä½æ¯å 为 Gopher
 类åå®ç°äºÂ code
Â æ¹æ³ï¼æä»¥è®©Â *Gopher
 类åèªå¨æ¥æäºÂ code
æ¹æ³ã
å½ç¶ï¼ä¸é¢çè¯´æ³æä¸ä¸ªç®åçè§£éï¼æ¥æ¶è æ¯æéç±»åçæ¹æ³ï¼å¾å¯è½å¨æ¹æ³ä¸ä¼å¯¹æ¥æ¶è ç屿§è¿è¡æ´æ¹æä½ï¼ä»è影忥æ¶è ï¼èå¯¹äºæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ï¼å¨æ¹æ³ä¸ä¸ä¼å¯¹æ¥æ¶è æ¬èº«äº§çå½±åã
æä»¥ï¼å½å®ç°äºä¸ä¸ªæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ï¼å°±å¯ä»¥èªå¨çæä¸ä¸ªæ¥æ¶è æ¯å¯¹åºæéç±»åçæ¹æ³ï¼å 为两è é½ä¸ä¼å½±åæ¥æ¶è ã使¯ï¼å½å®ç°äºä¸ä¸ªæ¥æ¶è æ¯æéç±»åçæ¹æ³ï¼å¦ææ¤æ¶èªå¨çæä¸ä¸ªæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ï¼åæ¬ææå¯¹æ¥æ¶è çæ¹åï¼éè¿æéå®ç°ï¼ï¼ç°å¨æ æ³å®ç°ï¼å 为å¼ç±»åä¼äº§çä¸ä¸ªæ·è´ï¼ä¸ä¼çæ£å½±åè°ç¨è ã
æåï¼åªè¦è®°ä½ä¸é¢è¿ç¹å°±å¯ä»¥äºï¼
妿å®ç°äºæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ï¼ä¼éå«å°ä¹å®ç°äºæ¥æ¶è æ¯æéç±»åçæ¹æ³ã
两è åå«å¨ä½æ¶ä½¿ç¨
å¦ææ¹æ³çæ¥æ¶è æ¯å¼ç±»åï¼æ 论è°ç¨è æ¯å¯¹è±¡è¿æ¯å¯¹è±¡æéï¼ä¿®æ¹ç齿¯å¯¹è±¡ç坿¬ï¼ä¸å½±åè°ç¨è ï¼å¦ææ¹æ³çæ¥æ¶è æ¯æéç±»åï¼åè°ç¨è ä¿®æ¹çæ¯æéæåç对象æ¬èº«ã
ä½¿ç¨æéä½ä¸ºæ¹æ³çæ¥æ¶è ççç±ï¼
â¢æ¹æ³è½å¤ä¿®æ¹æ¥æ¶è æåçå¼ã
â¢é¿å 卿¯æ¬¡è°ç¨æ¹æ³æ¶å¤å¶è¯¥å¼ï¼å¨å¼çç±»å为大åç»æä½æ¶ï¼è¿æ ·å伿´å 髿ã
æ¯ä½¿ç¨å¼æ¥æ¶è
è¿æ¯æéæ¥æ¶è
ï¼ä¸æ¯ç±è¯¥æ¹æ³æ¯å¦ä¿®æ¹äºè°ç¨è
ï¼ä¹å°±æ¯æ¥æ¶è
ï¼æ¥å³å®ï¼èæ¯åºè¯¥åºäºè¯¥ç±»åçæ¬è´¨
ã
å¦æç±»åå
·å¤âåå§çæ¬è´¨âï¼ä¹å°±æ¯è¯´å®çæå齿¯ç± Go è¯è¨éå
ç½®çåå§ç±»åï¼å¦åç¬¦ä¸²ï¼æ´åå¼çï¼é£å°±å®ä¹å¼æ¥æ¶è
ç±»åçæ¹æ³ãåå
ç½®çå¼ç¨ç±»åï¼å¦ sliceï¼mapï¼interfaceï¼channelï¼è¿äºç±»åæ¯è¾ç¹æ®ï¼å£°æä»ä»¬çæ¶åï¼å®é
䏿¯å建äºä¸ä¸ª header
ï¼ å¯¹äºä»ä»¬ä¹æ¯ç´æ¥å®ä¹å¼æ¥æ¶è
ç±»åçæ¹æ³ãè¿æ ·ï¼è°ç¨å½æ°æ¶ï¼æ¯ç´æ¥ copy äºè¿äºç±»åç header
ï¼è header
æ¬èº«å°±æ¯ä¸ºå¤å¶è®¾è®¡çã
å¦æç±»åå
·å¤éåå§çæ¬è´¨ï¼ä¸è½è¢«å®å
¨å°å¤å¶ï¼è¿ç§ç±»åæ»æ¯åºè¯¥è¢«å
±äº«ï¼é£å°±å®ä¹æéæ¥æ¶è
çæ¹æ³ãæ¯å¦ go æºç éçæä»¶ç»æä½ï¼struct Fileï¼å°±ä¸åºè¯¥è¢«å¤å¶ï¼åºè¯¥åªæä¸ä»½å®ä½
ã
è¿ä¸æ®µè¯´çæ¯è¾ç»ï¼å¤§å®¶å¯ä»¥å»çãGo è¯è¨å®æã5.3 é£ä¸èã
3. iface å eface çåºå«æ¯ä»ä¹
iface
 å eface
Â é½æ¯ Go ä¸æè¿°æ¥å£çåºå±ç»æä½ï¼åºå«å¨äºÂ iface
 æè¿°çæ¥å£å
嫿¹æ³ï¼è eface
忝ä¸å
å«ä»»ä½æ¹æ³ç空æ¥å£ï¼interface{}
ã
仿ºç å±é¢çä¸ä¸ï¼
iface
 å
é¨ç»´æ¤ä¸¤ä¸ªæéï¼tab
 æåä¸ä¸ªÂ itab
å®ä½ï¼ å®è¡¨ç¤ºæ¥å£çç±»å以åèµç»è¿ä¸ªæ¥å£çå®ä½ç±»åãdata
åæåæ¥å£å
·ä½çå¼ï¼ä¸è¬èè¨æ¯ä¸ä¸ªæåå å
åçæéã
忥ä»ç»çä¸ä¸Â itab
ç»æä½ï¼_type
åæ®µæè¿°äºå®ä½çç±»åï¼å
æ¬å
å坹齿¹å¼ï¼å¤§å°çï¼inter
åæ®µåæè¿°äºæ¥å£çç±»åãfun
åæ®µæ¾ç½®åæ¥å£æ¹æ³å¯¹åºçå
·ä½æ°æ®ç±»åçæ¹æ³å°åï¼å®ç°æ¥å£è°ç¨æ¹æ³ç卿忴¾ï¼ä¸è¬å¨æ¯æ¬¡ç»æ¥å£èµå¼åçè½¬æ¢æ¶ä¼æ´æ°æ¤è¡¨ï¼æè
ç´æ¥æ¿ç¼åç itabã
è¿éåªä¼ååºå®ä½ç±»å忥å£ç¸å ³çæ¹æ³ï¼å®ä½ç±»åçå ¶ä»æ¹æ³å¹¶ä¸ä¼åºç°å¨è¿éãå¦æä½ å¦è¿ C++ çè¯ï¼è¿éå¯ä»¥ç±»æ¯è彿°çæ¦å¿µã
å¦å¤ï¼ä½ å¯è½ä¼è§å¾å¥æªï¼ä¸ºä»ä¹Â fun
æ°ç»ç大å°ä¸º 1ï¼è¦æ¯æ¥å£å®ä¹äºå¤ä¸ªæ¹æ³å¯æä¹åï¼å®é
ä¸ï¼è¿éåå¨çæ¯ç¬¬ä¸ä¸ªæ¹æ³ç彿°æéï¼å¦æææ´å¤çæ¹æ³ï¼å¨å®ä¹åçå
å空é´éç»§ç»åå¨ã仿±ç¼è§åº¦æ¥çï¼éè¿å¢å å°åå°±è½è·åå°è¿äºå½æ°æéï¼æ²¡ä»ä¹å½±åã顺便æä¸å¥ï¼è¿äºæ¹æ³æ¯æç
§å½æ°åç§°çåå
¸åºè¿è¡æåçã
åçä¸ä¸Â interfacetype
ç±»åï¼å®æè¿°çæ¯æ¥å£çç±»åï¼
å¯ä»¥çå°ï¼å®å
è£
äºÂ _type
 类åï¼_type
å®é
䏿¯æè¿° Go è¯è¨ä¸åç§æ°æ®ç±»åçç»æä½ãæä»¬æ³¨æå°ï¼è¿éè¿å
å«ä¸ä¸ª mhdr
Â åæ®µï¼è¡¨ç¤ºæ¥å£æå®ä¹ç彿°å表ï¼Â pkgpath
è®°å½å®ä¹äºæ¥å£çå
åã
è¿ééè¿ä¸å¼ 徿¥çä¸Â iface
ç»æä½çå
¨è²ï¼
æ¥çæ¥çä¸ä¸Â eface
çæºç ï¼
ç¸æ¯Â iface
ï¼eface
å°±æ¯è¾ç®åäºãåªç»´æ¤äºä¸ä¸ª _type
åæ®µï¼è¡¨ç¤ºç©ºæ¥å£ææ¿è½½çå
·ä½çå®ä½ç±»åãdata
æè¿°äºå
·ä½çå¼ã
æä»¬æ¥ç个ä¾åï¼
æ§è¡å½ä»¤ï¼æå°åºæ±ç¼è¯è¨ï¼
å¯ä»¥çå°ï¼main 彿°éè°ç¨äºä¸¤ä¸ªå½æ°ï¼
ä¸é¢ä¸¤ä¸ªå½æ°çåæ°å iface
 å eface
ç»æä½çåæ®µæ¯å¯ä»¥è系起æ¥çï¼ä¸¤ä¸ªå½æ°é½æ¯å°åæ°ç»è£
ä¸ä¸ï¼å½¢ææç»çæ¥å£ã
ä½ä¸ºè¡¥å
ï¼æä»¬æå忥çä¸Â _type
ç»æä½ï¼
Go è¯è¨åç§æ°æ®ç±»å齿¯å¨Â _type
åæ®µçåºç¡ä¸ï¼å¢å ä¸äºé¢å¤çåæ®µæ¥è¿è¡ç®¡ççï¼
è¿äºæ°æ®ç±»åçç»æä½å®ä¹ï¼æ¯åå°å®ç°çåºç¡ã
4. æ¥å£çå¨æç±»åå卿å¼
仿ºç éå¯ä»¥çå°ï¼iface
å
å«ä¸¤ä¸ªå段ï¼tab
æ¯æ¥å£è¡¨æéï¼æåç±»åä¿¡æ¯ï¼data
æ¯æ°æ®æéï¼åæåå
·ä½çæ°æ®ãå®ä»¬åå«è¢«ç§°ä¸ºå¨æç±»å
å卿å¼
ãèæ¥å£å¼å
æ¬å¨æç±»å
å卿å¼
ã
ãå¼ç³1ãæ¥å£ç±»åå nil
Â ä½æ¯è¾
æ¥å£å¼çé¶å¼æ¯æå¨æç±»å
å卿å¼
é½ä¸ºÂ nil
ãå½ä»
ä¸å½è¿ä¸¤é¨åçå¼é½ä¸º nil
 çæ
åµä¸ï¼è¿ä¸ªæ¥å£å¼å°±æä¼è¢«è®¤ä¸ºÂ æ¥å£å¼ == nil
ã
æ¥ç个ä¾åï¼
è¾åºï¼
ä¸å¼å§ï¼c
 ç å¨æç±»åå卿å¼é½ä¸ºÂ nil
ï¼g
 ä¹ä¸ºÂ nil
ï¼å½æÂ g
 èµå¼ç»Â c
 åï¼c
 çå¨æç±»ååæäºÂ *main.Gopher
ï¼ä»
管 c
 ç卿å¼ä»ä¸ºÂ nil
ï¼ä½æ¯å½Â c
 å nil
Â ä½æ¯è¾çæ¶åï¼ç»æå°±æ¯Â false
äºã
ãå¼ç³2ã æ¥çä¸ä¸ªä¾åï¼çä¸ä¸å®çè¾åºï¼
彿°è¿è¡ç»æï¼
è¿éå
å®ä¹äºä¸ä¸ªÂ MyError
Â ç»æä½ï¼å®ç°äºÂ Error
Â å½æ°ï¼ä¹å°±å®ç°äºÂ error
æ¥å£ãProcess
Â å½æ°è¿åäºä¸ä¸ªÂ error
æ¥å£ï¼è¿åéå«äºç±»å转æ¢ãæä»¥ï¼è½ç¶å®ç弿¯ nil
ï¼å
¶å®å®çç±»åæ¯Â *MyError
ï¼æåå nil
 æ¯è¾çæ¶åï¼ç»æä¸ºÂ false
ã
ãå¼ç³3ãå¦ä½æå°åºæ¥å£çå¨æç±»ååå¼ï¼
ç´æ¥ç代ç ï¼
代ç éç´æ¥å®ä¹äºä¸ä¸ªÂ iface
Â ç»æä½ï¼ç¨ä¸¤ä¸ªæéæ¥æè¿°Â itab
 å data
ï¼ä¹åå° a, b, c å¨å
åä¸çå
容强å¶è§£éææä»¬èªå®ä¹ç iface
ãæåå°±å¯ä»¥æå°åºå¨æç±»åå卿å¼çå°åã
è¿è¡ç»æå¦ä¸ï¼
a çå¨æç±»åå卿å¼çå°åå为 0ï¼ä¹å°±æ¯ nilï¼b çå¨æç±»åå c çå¨æç±»åä¸è´ï¼é½æ¯ *int
ï¼æåï¼c ç卿å¼ä¸º 5ã
5. ç¼è¯å¨èªå¨æ£æµç±»åæ¯å¦å®ç°æ¥å£
ç»å¸¸çå°ä¸äºå¼æºåºé伿ä¸äºç±»ä¼¼ä¸é¢è¿ç§å¥æªçç¨æ³ï¼
è¿æ¶åä¼æç¹æµï¼ä¸ç¥éä½è
æ³è¦å¹²ä»ä¹ï¼å®é
ä¸è¿å°±æ¯æ¤é®é¢ççæ¡ãç¼è¯å¨ä¼ç±æ¤æ£æ¥ *myWriter
Â ç±»åæ¯å¦å®ç°äºÂ io.Writer
æ¥å£ã
æ¥çä¸ä¸ªä¾åï¼
注éæä¸º myWriter å®ä¹ç Write 彿°åï¼è¿è¡ç¨åºï¼
æ¥éä¿¡æ¯ï¼*myWriter/myWriter æªå®ç° io.Writer æ¥å£ï¼ä¹å°±æ¯æªå®ç° Write æ¹æ³ã
è§£é¤æ³¨éåï¼è¿è¡ç¨åºä¸æ¥éã
å®é ä¸ï¼ä¸è¿°èµå¼è¯å¥ä¼åçéå¼å°ç±»å转æ¢ï¼å¨è½¬æ¢çè¿ç¨ä¸ï¼ç¼è¯å¨ä¼æ£æµçå·å³è¾¹çç±»åæ¯å¦å®ç°äºçå·å·¦è¾¹æ¥å£æè§å®ç彿°ã
æ»ç»ä¸ä¸ï¼å¯éè¿å¨ä»£ç 䏿·»å 类似å¦ä¸ç代ç ï¼ç¨æ¥æ£æµç±»åæ¯å¦å®ç°äºæ¥å£ï¼
6. æ¥å£çæé è¿ç¨æ¯ææ ·ç
æä»¬å·²ç»çè¿äºÂ iface
 å eface
Â çæºç ï¼ç¥é iface
 æéè¦çæ¯Â itab
 å _type
ã
为äºç ç©¶æ¸ æ¥æ¥å£æ¯å¦ä½æé çï¼æ¥ä¸æ¥æä¼æ¿èµ·æ±ç¼çæ¦å¨ï¼è¿åèåççç¸ã
æ¥çä¸ä¸ªç¤ºä¾ä»£ç ï¼
æ§è¡å½ä»¤ï¼
å¾å° main 彿°çæ±ç¼ä»£ç å¦ä¸ï¼
æä»¬ä»ç¬¬ 10 è¡å¼å§çï¼å¦æä¸çè§£åé¢å è¡æ±ç¼ä»£ç çè¯ï¼å¯ä»¥åå»ççå ¬ä¼å·åé¢ä¸¤ç¯æç« ï¼è¿éæå°±çç¥äºã
æ±ç¼è¡æ° |
æä½ |
10-14 |
æé è°ç¨Â |
æä»¬æ¥çä¸è¿ä¸ªå½æ°çåæ°å½¢å¼ï¼
convT2I64
Â ä¼æé åºä¸ä¸ªÂ inteface
ï¼ä¹å°±æ¯æä»¬ç Person
æ¥å£ã
第ä¸ä¸ªåæ°çä½ç½®æ¯Â (SP)
ï¼è¿é被èµä¸äºÂ go.itab."".Student,"".Person(SB)
çå°åã
æä»¬ä»çæçæ±ç¼æ¾å°ï¼
size=40
大å°ä¸º40åèï¼å顾ä¸ä¸ï¼
ææ¯ä¸ªåæ®µç大å°ç¸å ï¼itab
ç»æä½ç大å°å°±æ¯ 40 åèãä¸é¢é£ä¸ä¸²æ°åå®é
䏿¯ itab
 åºåååçå
å®¹ï¼æ³¨æå°å¤§é¨åæ°åæ¯ 0ï¼ä» 24 åèå¼å§ç 4 个åè da 9f 20 d4
 å®é
䏿¯Â itab
 ç hash
å¼ï¼è¿å¨å¤æä¸¤ä¸ªç±»åæ¯å¦ç¸åçæ¶åä¼ç¨å°ã
ä¸é¢ä¸¤è¡æ¯é¾æ¥æä»¤ï¼ç®å说就æ¯å°æææºæä»¶ç»¼åèµ·æ¥ï¼ç»æ¯ä¸ªç¬¦å·èµäºä¸ä¸ªå
¨å±çä½ç½®å¼ãè¿éçææä¹æ¯è¾æç¡®ï¼å8个åèæç»åå¨çæ¯ type."".Person
 çå°åï¼å¯¹åºÂ itab
 éç inter
åæ®µï¼è¡¨ç¤ºæ¥å£ç±»åï¼8-16 åèæç»åå¨çæ¯ type."".Student
 çå°åï¼å¯¹åºÂ itab
 é _type
åæ®µï¼è¡¨ç¤ºå
·ä½ç±»åã
第äºä¸ªåæ°å°±æ¯è¾ç®åäºï¼å®å°±æ¯æ°å 18
 çå°åï¼è¿ä¹æ¯åå§å Student
ç»æä½çæ¶åä¼ç¨å°ã
æ±ç¼è¡æ° |
æä½ |
15 |
è°ç¨Â |
å ·ä½çä¸ä»£ç ï¼
âè¿åä»£ç æ¯è¾ç®åï¼æÂ tab
 èµç»äºÂ iface
 ç tab
åæ®µï¼data
 é¨å忝å¨å ä¸ç³è¯·äºä¸åå
åï¼ç¶åå°Â elem
 æåç 18
æ·è´è¿å»ãè¿æ · iface
å°±ç»è£
好äºã
æ±ç¼è¡æ° |
æä½ |
17 |
æÂ |
18 |
æÂ |
19-21 |
æ£æµÂ |
åé¢ï¼å°±æ¯è°ç¨Â fmt.Println
彿°åä¹åçåæ°åå¤å·¥ä½äºï¼ä¸åèµè¿°ã
è¿æ ·ï¼æä»¬å°±æä¸ä¸ªÂ interface
çæé è¿ç¨è¯´å®äºã
ãå¼ç³1ã å¦ä½æå°åºæ¥å£ç±»åç Hash
å¼ï¼
è¿éåèæ¹å¤§ç¥ç¿»è¯çä¸ç¯æç« ï¼åèèµæéä¼åä¸ãå ·ä½åæ³å¦ä¸ï¼
âäºä¸ä¸ªå±±å¯¨ç
ç iface
 å itab
ï¼è¯´å®å±±å¯¨
æ¯å 为 itab
 éçä¸äºå
³é®æ°æ®ç»æé½ä¸å
·ä½å±å¼äºï¼æ¯å¦Â _type
ï¼å¯¹æ¯ä¸ä¸æ£å®çå®ä¹å°±å¯ä»¥åç°ï¼ä½æ¯å±±å¯¨ç
ä¾ç¶è½å·¥ä½ï¼å 为 _type
å°±æ¯ä¸ä¸ªæéèå·²åã
å¨Â main
Â å½æ°éï¼å
æé åºä¸ä¸ªæ¥å£å¯¹è±¡Â qcrao
ï¼ç¶å强å¶ç±»å转æ¢ï¼æå读ååºÂ hash
å¼ï¼é常å¦ï¼ä½ ä¹å¯ä»¥èªå·±å¨æè¯ä¸ä¸ã
è¿è¡ç»æï¼
å¼å¾ä¸æçæ¯ï¼æé æ¥å£Â qcrao
Â çæ¶åï¼å³ä½¿ææÂ age
 åæå
¶ä»å¼ï¼å¾å°ç hash
 å¼ä¾ç¶ä¸åçï¼è¿åºè¯¥æ¯å¯ä»¥é¢æçï¼hash
å¼åªåä»çåæ®µãæ¹æ³ç¸å
³ã
7. ç±»å转æ¢åæè¨çåºå«
æä»¬ç¥éï¼Go è¯è¨ä¸ä¸å
许éå¼ç±»å转æ¢ï¼ä¹å°±æ¯è¯´Â =
两边ï¼ä¸å
许åºç°ç±»åä¸ç¸åçåéã
ç±»å转æ¢
ãç±»åæè¨
æ¬è´¨é½æ¯æä¸ä¸ªç±»åè½¬æ¢æå¦å¤ä¸ä¸ªç±»åãä¸åä¹å¤å¨äºï¼ç±»åæè¨æ¯å¯¹æ¥å£åéè¿è¡çæä½ã
ç±»å转æ¢
对äºç±»å转æ¢
èè¨ï¼è½¬æ¢ååç两个类åè¦ç¸äºå
¼å®¹æè¡ãç±»å转æ¢çè¯æ³ä¸ºï¼
<ç»æç±»å> := <ç®æ ç±»å> (<表达å¼>)
ä¸é¢ç代ç éï¼æå®ä¹äºä¸ä¸ªÂ int
 åå float64
åçåéï¼å°è¯å¨å®ä»¬ä¹åç¸äºè½¬æ¢ï¼ç»ææ¯æåçï¼int
 åå float64
æ¯ç¸äºå
¼å®¹çã
å¦ææææåä¸è¡ä»£ç çæ³¨é廿ï¼ç¼è¯å¨ä¼æ¥åç±»åä¸å ¼å®¹çé误ï¼
âæè¨
åé¢è¯´è¿ï¼å 为空æ¥å£Â interface{}
没æå®ä¹ä»»ä½å½æ°ï¼å æ¤ Go 䏿æç±»åé½å®ç°äºç©ºæ¥å£ãå½ä¸ä¸ªå½æ°ç形忝 interface{}
ï¼é£ä¹å¨å½æ°ä¸ï¼éè¦å¯¹å½¢åè¿è¡æè¨ï¼ä»èå¾å°å®ççå®ç±»åã
æè¨çè¯æ³ä¸ºï¼
 // å®å ¨ç±»åæè¨
<ç®æ ç±»åçå¼>ï¼<å¸å°åæ°> := <表达å¼>.( ç®æ ç±»å ) Â
//éå®å ¨ç±»åæè¨
<ç®æ ç±»åçå¼> := <表达å¼>.( ç®æ ç±»å )
ç±»å转æ¢åç±»åæè¨æäºç¸ä¼¼ï¼ä¸åä¹å¤ï¼å¨äºç±»åæè¨æ¯å¯¹æ¥å£è¿è¡çæä½ã
è¿æ¯æ¥çä¸ä¸ªç®ççä¾åï¼
âè¿è¡ä¸ä¸ï¼
âç´æ¥Â panic
 äºï¼è¿æ¯å 为 i
 æ¯Â *Student
 类åï¼å¹¶é Student
ç±»åï¼æè¨å¤±è´¥ãè¿éç´æ¥åçäº panic
ï¼çº¿ä¸ä»£ç å¯è½å¹¶ä¸éåè¿æ ·åï¼å¯ä»¥éç¨âå®å
¨æè¨âçè¯æ³ï¼
è¿æ ·ï¼å³ä½¿æè¨å¤±è´¥ä¹ä¸ä¼Â panic
ã
æè¨å
¶å®è¿æå¦ä¸ç§å½¢å¼ï¼å°±æ¯ç¨å¨å©ç¨Â switch
è¯å¥å¤ææ¥å£çç±»åãæ¯ä¸ä¸ª case
ä¼è¢«é¡ºåºå°èèãå½å½ä¸ä¸ä¸ª case
 æ¶ï¼å°±ä¼æ§è¡Â case
 ä¸çè¯å¥ï¼å æ¤Â case
 è¯å¥çé¡ºåºæ¯å¾éè¦çï¼å ä¸ºå¾æå¯è½ä¼æå¤ä¸ªÂ case
å¹é
çæ
åµã
代ç 示ä¾å¦ä¸ï¼
main
彿°éæä¸è¡ä¸åç声æï¼æ¯æ¬¡è¿è¡ä¸è¡ï¼æ³¨éå¦å¤ä¸¤è¡ï¼å¾å°ä¸ç»è¿è¡ç»æï¼
对äºç¬¬ä¸è¡è¯å¥ï¼
âi
 æ¯ä¸ä¸ªÂ *Student
ç±»åï¼å¹é
ä¸ç¬¬ä¸ä¸ª caseï¼ä»æå°çä¸ä¸ªå°åæ¥çï¼è¿ä¸å¤çåéå®é
ä¸é½æ¯ä¸ä¸æ ·çãå¨ main
Â å½æ°éæä¸ä¸ªå±é¨åé i
ï¼è°ç¨å½æ°æ¶ï¼å®é
䏿¯å¤å¶äºä¸ä»½åæ°ï¼å æ¤å½æ°éåæä¸ä¸ªåé v
ï¼å®æ¯Â i
çæ·è´ï¼æè¨ä¹åï¼åçæäºä¸ä»½æ°çæ·è´ãæä»¥æç»æå°çä¸ä¸ªåéçå°åé½ä¸ä¸æ ·ã
对äºç¬¬äºè¡è¯å¥ï¼
âè¿éæ³è¯´æçå
¶å®æ¯Â i
 å¨è¿éå¨æç±»åæ¯Â (*Student)
, æ°æ®ä¸ºÂ nil
ï¼å®çç±»å并䏿¯Â nil
ï¼å®ä¸Â nil
Â ä½æ¯è¾çæ¶åï¼å¾å°çç»æä¹æ¯Â false
ã
æåä¸è¡è¯å¥ï¼
è¿å i
Â ææ¯Â nil
ç±»åã
ãå¼ç³1ã fmt.Println
Â å½æ°çåæ°æ¯Â interface
ã对äºå
置类åï¼å½æ°å
é¨ä¼ç¨ç©·ä¸¾æ³ï¼å¾åºå®ççå®ç±»åï¼ç¶å转æ¢ä¸ºå符串æå°ãè对äºèªå®ä¹ç±»åï¼é¦å
ç¡®å®è¯¥ç±»åæ¯å¦å®ç°äº String()
Â æ¹æ³ï¼å¦æå®ç°äºï¼åç´æ¥æå°è¾åºÂ String()
æ¹æ³çç»æï¼å¦åï¼ä¼éè¿åå°æ¥éå对象çæåè¿è¡æå°ã
忥çä¸ä¸ªç®ççä¾åï¼æ¯è¾ç®åï¼ä¸è¦ç´§å¼ ï¼
âå 为 Student
Â ç»æä½æ²¡æå®ç°Â String()
Â æ¹æ³ï¼æä»¥Â fmt.Println
ä¼å©ç¨åå°æ¨ä¸ªæå°æååéï¼
âå¢å ä¸ä¸ªÂ String()
æ¹æ³çå®ç°ï¼
æå°ç»æï¼
âæç §æä»¬èªå®ä¹çæ¹æ³æ¥æå°äºã
ãå¼ç³2ã é对ä¸é¢çä¾åï¼å¦ææ¹ä¸ä¸ï¼
注æçä¸¤ä¸ªå½æ°çæ¥åè
ç±»åä¸åï¼ç°å¨Â Student
Â ç»æä½åªæä¸ä¸ªæ¥åè
ç±»å为 æéç±»å
 ç String()
彿°ï¼æå°ç»æï¼
â为ä»ä¹ï¼
ç±»åÂ
T
Â åªææ¥åè æ¯ÂT
çæ¹æ³ï¼èç±»å*T
Â æ¥ææ¥åè æ¯ÂT
 åÂ*T
çæ¹æ³ãè¯æ³ä¸T
 è½ç´æ¥è°Â*T
Â çæ¹æ³ä» ä» æ¯ÂGo
çè¯æ³ç³ã
æä»¥ï¼Â Student
Â ç»æä½å®ä¹äºæ¥åè
ç±»åæ¯å¼ç±»åç String()
Â æ¹æ³æ¶ï¼éè¿
åå¯ä»¥æç §èªå®ä¹çæ ¼å¼æ¥æå°ã
å¦æÂ Student
Â ç»æä½å®ä¹äºæ¥åè
ç±»åæ¯æéç±»åç String()
Â æ¹æ³æ¶ï¼åªæéè¿
æè½æç §èªå®ä¹çæ ¼å¼æå°ã
8. æ¥å£è½¬æ¢çåç
éè¿å颿å°ç iface
Â çæºç å¯ä»¥çå°ï¼å®é
ä¸å®å
嫿¥å£çç±»å interfacetype
 å å®ä½ç±»åçç±»å _type
ï¼è¿ä¸¤è
齿¯Â iface
 çåæ®µÂ itab
çæåãä¹å°±æ¯è¯´çæä¸ä¸ª itab
åæ¶éè¦æ¥å£çç±»ååå®ä½çç±»åã
<interface ç±»åï¼ å®ä½ç±»å> ->itable
å½å¤å®ä¸ç§ç±»åæ¯å¦æ»¡è¶³æä¸ªæ¥å£æ¶ï¼Go 使ç¨ç±»åçæ¹æ³é忥壿éè¦çæ¹æ³éè¿è¡å¹é ï¼å¦æç±»åçæ¹æ³éå®å ¨å 嫿¥å£çæ¹æ³éï¼åå¯è®¤ä¸ºè¯¥ç±»åå®ç°äºè¯¥æ¥å£ã
ä¾å¦æç±»åæÂ m
Â ä¸ªæ¹æ³ï¼ææ¥å£æÂ n
Â ä¸ªæ¹æ³ï¼åå¾å®¹æç¥éè¿ç§å¤å®çæ¶é´å¤æåº¦ä¸ºÂ O(mn)
ï¼Go ä¼å¯¹æ¹æ³éç彿°æç
§å½æ°åçåå
¸åºè¿è¡æåºï¼æä»¥å®é
çæ¶é´å¤æåº¦ä¸ºÂ O(m+n)
ã
è¿éæä»¬æ¥æ¢ç´¢å°ä¸ä¸ªæ¥å£è½¬æ¢ç»å¦å¤ä¸ä¸ªæ¥å£èåçåçï¼å½ç¶ï¼è½è½¬æ¢çåå å¿ ç¶æ¯ç±»åå ¼å®¹ã
ç´æ¥æ¥çä¸ä¸ªä¾åï¼
ç®åè§£éä¸ä¸è¿°ä»£ç ï¼å®ä¹äºä¸¤ä¸ª interface
:Â coder
 å runner
ãå®ä¹äºä¸ä¸ªå®ä½ç±»å Gopher
ï¼ç±»å Gopher
 å®ç°äºä¸¤ä¸ªæ¹æ³ï¼å嫿¯Â run()
 å code()
ãmain 彿°éå®ä¹äºä¸ä¸ªæ¥å£åé c
ï¼ç»å®äºä¸ä¸ªÂ Gopher
 对象ï¼ä¹åå°Â c
 èµå¼ç»å¦å¤ä¸ä¸ªæ¥å£åé r
ãèµå¼æåçåå æ¯ c
 ä¸å
å«Â run()
æ¹æ³ãè¿æ ·ï¼ä¸¤ä¸ªæ¥å£åé宿äºè½¬æ¢ã
æ§è¡å½ä»¤ï¼
âå¾å° main 彿°çæ±ç¼å½ä»¤ï¼å¯ä»¥çå°ï¼r = c
 è¿ä¸è¡è¯å¥å®é
䏿¯è°ç¨äºÂ runtime.convI2I(SB)
ï¼ä¹å°±æ¯Â convI2I
Â å½æ°ï¼ä»å½æ°åæ¥çï¼å°±æ¯å°ä¸ä¸ªÂ interface
Â è½¬æ¢æå¦å¤ä¸ä¸ªÂ interface
ï¼çä¸å®çæºä»£ç ï¼
ä»£ç æ¯è¾ç®åï¼å½æ°åæ°Â inter
 表示æ¥å£ç±»åï¼i
 表示ç»å®äºå®ä½ç±»åçæ¥å£ï¼r
 å表示æ¥å£è½¬æ¢äºä¹åçæ°ç iface
ãéè¿åé¢çåæï¼æä»¬åç¥éï¼ iface
 æ¯ç±Â tab
 å data
ä¸¤ä¸ªåæ®µç»æãæä»¥ï¼å®é
ä¸ convI2I
Â å½æ°çæ£è¦åçäºï¼æ¾å°æ°Â interface
 ç tab
 å data
ï¼å°±å¤§ååæäºã
æä»¬è¿ç¥éï¼tab
 æ¯ç±æ¥å£ç±»å interfacetype
 å å®ä½ç±»å _type
ãæä»¥æå
³é®çè¯å¥æ¯ r.tab = getitab(inter, tab._type, false)
ã
å æ¤ï¼éç¹æ¥çä¸Â getitab
彿°çæºç ï¼åªçå
³é®çå°æ¹ï¼
ç®åæ»ç»ä¸ä¸ï¼getitab 彿°ä¼æ ¹æ® interfacetype
 å _type
å»å
¨å±ç itab åå¸è¡¨ä¸æ¥æ¾ï¼å¦æè½æ¾å°ï¼åç´æ¥è¿åï¼å¦åï¼ä¼æ ¹æ®ç»å®ç interfacetype
 å _type
 æ°çæä¸ä¸ªÂ itab
ï¼å¹¶æå
¥å° itab åå¸è¡¨ï¼è¿æ ·ä¸ä¸æ¬¡å°±å¯ä»¥ç´æ¥æ¿å°Â itab
ã
è¿éæ¥æ¾äºä¸¤æ¬¡ï¼å¹¶ä¸ç¬¬äºæ¬¡ä¸éäºï¼è¿æ¯å ä¸ºå¦æç¬¬ä¸æ¬¡æ²¡æ¾å°ï¼å¨ç¬¬äºæ¬¡ä»ç¶æ²¡ææ¾å°ç¸åºç itab
çæ
åµä¸ï¼éè¦æ°çæä¸ä¸ªï¼å¹¶ä¸åå
¥åå¸è¡¨ï¼å æ¤éè¦å éãè¿æ ·ï¼å
¶ä»åç¨å¨æ¥æ¾ç¸åç itab
 并ä¸ä¹æ²¡ææ¾å°æ¶ï¼ç¬¬äºæ¬¡æ¥æ¾æ¶ï¼ä¼è¢«æä½ï¼ä¹åï¼å°±ä¼æ¥å°ç¬¬ä¸ä¸ªåç¨åå
¥åå¸è¡¨ç itab
ã
忥çä¸ä¸Â additab
彿°ç代ç ï¼
additab
Â ä¼æ£æ¥Â itab
 ææç interfacetype
 å _type
 æ¯å¦ç¬¦åï¼å°±æ¯ç _type
 æ¯å¦å®å
¨å®ç°äºÂ interfacetype
Â çæ¹æ³ï¼ä¹å°±æ¯ç两è
çæ¹æ³å表éå çé¨åå°±æ¯Â interfacetype
æææçæ¹æ³åè¡¨ãæ³¨æå°å
¶ä¸æä¸ä¸ªåå±å¾ªç¯ï¼ä¹ä¸çï¼å¾ªç¯æ¬¡æ°æ¯ ni * nt
ï¼ä½ç±äºä¸¤è
ç彿°åè¡¨é½æç
§å½æ°åç§°è¿è¡äºæåºï¼å æ¤æç»åªæ§è¡äºÂ ni + nt
次ï¼ä»£ç ééè¿ä¸ä¸ªå°æå·§æ¥å®ç°ï¼ç¬¬äºå±å¾ªç¯å¹¶æ²¡æä» 0 å¼å§è®¡æ°ï¼èæ¯ä»ä¸ä¸æ¬¡éåå°çä½ç½®å¼å§ã
æ± hash å¼ç彿°æ¯è¾ç®åï¼
hashSize
ç弿¯ 1009ã
æ´ä¸è¬çï¼å½æå®ä½ç±»åèµå¼ç»æ¥å£çæ¶åï¼ä¼è°ç¨Â conv
 系å彿°ï¼ä¾å¦ç©ºæ¥å£è°ç¨Â convT2E
 系åãé空æ¥å£è°ç¨Â convT2I
ç³»åãè¿äºå½æ°æ¯è¾ç¸ä¼¼ï¼
1.å ·ä½ç±»å转空æ¥å£æ¶ï¼_type åæ®µç´æ¥å¤å¶æºç±»åç _typeï¼è°ç¨ mallocgc è·å¾ä¸åæ°å åï¼æå¼å¤å¶è¿å»ï¼data åæåè¿åæ°å åã
2.å ·ä½ç±»å转é空æ¥å£æ¶ï¼å ¥å tab æ¯ç¼è¯å¨å¨ç¼è¯é¶æ®µé¢å çæå¥½çï¼æ°æ¥å£ tab åæ®µç´æ¥æåå ¥å tab æåç itabï¼è°ç¨ mallocgc è·å¾ä¸åæ°å åï¼æå¼å¤å¶è¿å»ï¼data åæåè¿åæ°å åã
3.èå¯¹äºæ¥å£è½¬æ¥å£ï¼itab è°ç¨ getitab 彿°è·åãåªç¨çæä¸æ¬¡ï¼ä¹åç´æ¥ä» hash 表ä¸è·åã
9. å¦ä½ç¨ interface å®ç°å¤æ
Go
è¯è¨å¹¶æ²¡æè®¾è®¡è¯¸å¦è彿°ã纯è彿°ãç»§æ¿ãå¤éç»§æ¿çæ¦å¿µï¼ä½å®éè¿æ¥å£å´é常ä¼é
å°æ¯æäºé¢å对象çç¹æ§ã
夿æ¯ä¸ç§è¿è¡æçè¡ä¸ºï¼å®æä»¥ä¸å 个ç¹ç¹ï¼
1.ä¸ç§ç±»åå ·æå¤ç§ç±»åçè½å
2.å 许ä¸åç对象对å䏿¶æ¯ååºçµæ´»çååº
3.以ä¸ç§éç¨çæ¹å¼å¯¹å¾ 个使ç¨ç对象
4.é卿è¯è¨å¿ é¡»éè¿ç»§æ¿åæ¥å£çæ¹å¼æ¥å®ç°
çä¸ä¸ªå®ç°äºå¤æç代ç ä¾åï¼
â代ç éå
å®ä¹äº 1 个 Person
æ¥å£ï¼å
å«ä¸¤ä¸ªå½æ°ï¼
ç¶åï¼åå®ä¹äº 2 ä¸ªç»æä½ï¼Student
 å Programmer
ï¼åæ¶ï¼ç±»å *Student
ãProgrammer
 å®ç°äºÂ Person
æ¥å£å®ä¹çä¸¤ä¸ªå½æ°ã注æï¼*Student
 类åå®ç°äºæ¥å£ï¼Â Student
ç±»åå´æ²¡æã
ä¹åï¼æåå®ä¹äºå½æ°åæ°æ¯Â Person
æ¥å£çä¸¤ä¸ªå½æ°ï¼
main
Â å½æ°éå
çæÂ Student
 å Programmer
 ç对象ï¼åå°å®ä»¬åå«ä¼ å
¥å°å½æ°Â whatJob
 å growUp
ã彿°ä¸ï¼ç´æ¥è°ç¨æ¥å£å½æ°ï¼å®é
æ§è¡çæ¶åæ¯çæç»ä¼ å
¥çå®ä½ç±»åæ¯ä»ä¹ï¼è°ç¨çæ¯å®ä½ç±»åå®ç°ç彿°ãäºæ¯ï¼ä¸å对象é对å䏿¶æ¯å°±æå¤ç§è¡¨ç°ï¼å¤æ
å°±å®ç°äºã
æ´æ·±å
¥ä¸ç¹æ¥è¯´çè¯ï¼å¨å½æ°Â whatJob()
 æè
 growUp()
 å
é¨ï¼æ¥å£Â person
 ç»å®äºå®ä½ç±»å *Student
 æè
 Programmer
ãæ ¹æ®åé¢åæç iface
 æºç ï¼è¿éä¼ç´æ¥è°ç¨Â fun
éä¿åç彿°ï¼ç±»ä¼¼äºï¼s.tab->fun[0]
ï¼èå 为 fun
æ°ç»éä¿åçæ¯å®ä½ç±»åå®ç°ç彿°ï¼æä»¥å½å½æ°ä¼ å
¥ä¸åçå®ä½ç±»åæ¶ï¼è°ç¨çå®é
䏿¯ä¸åç彿°å®ç°ï¼ä»èå®ç°å¤æã
è¿è¡ä¸ä¸ä»£ç ï¼
10. Go æ¥å£ä¸ C++ æ¥å£æä½å¼å
æ¥å£å®ä¹äºä¸ç§è§èï¼æè¿°äºç±»çè¡ä¸ºååè½ï¼èä¸åå ·ä½å®ç°ã
C++ çæ¥å£æ¯ä½¿ç¨æ½è±¡ç±»æ¥å®ç°çï¼å¦æç±»ä¸è³å°æä¸ä¸ªå½æ°è¢«å£°æä¸ºçº¯è彿°ï¼åè¿ä¸ªç±»å°±æ¯æ½è±¡ç±»ã纯è彿°æ¯éè¿å¨å£°æä¸ä½¿ç¨ "= 0" æ¥æå®çãä¾å¦ï¼
def hello_world(coder):
coder.say_hello()
type IGreeting interface {
sayHello()
}
func sayHello(i IGreeting) {
i.sayHello()
}
type Go struct {}
func (g Go) sayHello() {
fmt.Println("Hi, I am GO!")
}
type PHP struct {}
func (p PHP) sayHello() {
fmt.Println("Hi, I am PHP!")
}
func main() {
golang := Go{}
php := PHP{}
sayHello(golang)
sayHello(php)
}
Hi, I am GO!
Hi, I am PHP!
package main
import "fmt"
type Person struct {
age int
}
func (p Person) howOld() int {
return p.age
}
func (p *Person) growUp() {
p.age += 1
}
func main() {
// qcrao æ¯å¼ç±»å
qcrao := Person{age: 18}
// å¼ç±»å è°ç¨æ¥æ¶è
乿¯å¼ç±»åçæ¹æ³
fmt.Println(qcrao.howOld())
// å¼ç±»å è°ç¨æ¥æ¶è
æ¯æéç±»åçæ¹æ³
qcrao.growUp()
fmt.Println(qcrao.howOld())
// ----------------------
// stefno æ¯æéç±»å
stefno := &Person{age: 100}
// æéç±»å è°ç¨æ¥æ¶è
æ¯å¼ç±»åçæ¹æ³
fmt.Println(stefno.howOld())
// æéç±»å è°ç¨æ¥æ¶è
乿¯æéç±»åçæ¹æ³
stefno.growUp()
fmt.Println(stefno.howOld())
}
18
19
100
101
package main
import "fmt"
type coder interface {
code()
debug()
}
type Gopher struct {
language string
}
func (p Gopher) code() {
fmt.Printf("I am coding %s language\n", p.language)
}
func (p *Gopher) debug() {
fmt.Printf("I am debuging %s language\n", p.language)
}
func main() {
var c coder = &Gopher{"Go"}
c.code()
c.debug()
}
code()
debug()
I am coding Go language
I am debuging Go language
func main() {
var c coder = Gopher{"Go"}
c.code()
c.debug()
}
./main.go:24:6: cannot use Programmer literal (type Programmer) as type coder in assignment:
Programmer does not implement coder (debug method has pointer receiver)
type iface struct {
tab *itab
data unsafe.Pointer
}
type itab struct {
inter *interfacetype
_type *_type
link *itab
hash uint32 // copy of _type.hash. Used for type switches.
bad bool // type does not implement interface
inhash bool // has this itab been added to hash?
unused [2]byte
fun [1]uintptr // variable sized
}
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
type eface struct {
_type *_type
data unsafe.Pointer
}
package main
import "fmt"
func main() {
x := 200
var any interface{} = x
fmt.Println(any)
g := Gopher{"Go"}
var c coder = g
fmt.Println(c)
}
type coder interface {
code()
debug()
}
type Gopher struct {
language string
}
func (p Gopher) code() {
fmt.Printf("I am coding %s language\n", p.language)
}
func (p Gopher) debug() {
fmt.Printf("I am debuging %s language\n", p.language)
}
go tool compile -S ./src/main.go
func convT2E64(t *_type, elem unsafe.Pointer) (e eface)
func convT2I(tab *itab, elem unsafe.Pointer) (i iface)
type _type struct {
// ç±»å大å°
size uintptr
ptrdata uintptr
// ç±»åç hash å¼
hash uint32
// ç±»åç flagï¼ååå°ç¸å
³
tflag tflag
// å
å对é½ç¸å
³
align uint8
fieldalign uint8
// ç±»åçç¼å·ï¼æbool, slice, struct çççç
kind uint8
alg *typeAlg
// gc ç¸å
³
gcdata *byte
str nameOff
ptrToThis typeOff
}
type arraytype struct {
typ _type
elem *_type
slice *_type
len uintptr
}
type chantype struct {
typ _type
elem *_type
dir uintptr
}
type slicetype struct {
typ _type
elem *_type
}
type structtype struct {
typ _type
pkgPath name
fields []structfield
}
package main
import "fmt"
type Coder interface {
code()
}
type Gopher struct {
name string
}
func (g Gopher) code() {
fmt.Printf("%s is coding\n", g.name)
}
func main() {
var c Coder
fmt.Println(c == nil)
fmt.Printf("c: %T, %v\n", c, c)
var g *Gopher
fmt.Println(g == nil)
c = g
fmt.Println(c == nil)
fmt.Printf("c: %T, %v\n", c, c)
}
true
c: <nil>, <nil>
true
false
c: *main.Gopher, <nil>
package main
import "fmt"
type MyError struct {}
func (i MyError) Error() string {
return "MyError"
}
func main() {
err := Process()
fmt.Println(err)
fmt.Println(err == nil)
}
func Process() error {
var err *MyError = nil
return err
}
<nil>
false
package main
import (
"unsafe"
"fmt"
)
type iface struct {
itab, data uintptr
}
func main() {
var a interface{} = nil
var b interface{} = (*int)(nil)
x := 5
var c interface{} = (*int)(&x)
ia := *(*iface)(unsafe.Pointer(&a))
ib := *(*iface)(unsafe.Pointer(&b))
ic := *(*iface)(unsafe.Pointer(&c))
fmt.Println(ia, ib, ic)
fmt.Println(*(*int)(unsafe.Pointer(ic.data)))
}
{0 0} {17426912 0} {17426912 842350714568}
5
var _ io.Writer = (*myWriter)(nil)
package main
import "io"
type myWriter struct {
}
/*func (w myWriter) Write(p []byte) (n int, err error) {
return
}*/
func main() {
// æ£æ¥ *myWriter ç±»åæ¯å¦å®ç°äº io.Writer æ¥å£
var _ io.Writer = (*myWriter)(nil)
// æ£æ¥ myWriter ç±»åæ¯å¦å®ç°äº io.Writer æ¥å£
var _ io.Writer = myWriter{}
}
src/main.go:14:6: cannot use (*myWriter)(nil) (type *myWriter) as type io.Writer in assignment:
*myWriter does not implement io.Writer (missing Write method)
src/main.go:15:6: cannot use myWriter literal (type myWriter) as type io.Writer in assignment:
myWriter does not implement io.Writer (missing Write method)
var _ io.Writer = (*myWriter)(nil)
var _ io.Writer = myWriter{}
package main
import "fmt"
type Person interface {
growUp()
}
type Student struct {
age int
}
func (p Student) growUp() {
p.age += 1
return
}
func main() {
var qcrao = Person(Student{age: 18})
fmt.Println(qcrao)
}
go tool compile -S ./src/main.go
0x0000 00000 (./src/main.go:30) TEXT "".main(SB), $80-0
0x0000 00000 (./src/main.go:30) MOVQ (TLS), CX
0x0009 00009 (./src/main.go:30) CMPQ SP, 16(CX)
0x000d 00013 (./src/main.go:30) JLS 157
0x0013 00019 (./src/main.go:30) SUBQ $80, SP
0x0017 00023 (./src/main.go:30) MOVQ BP, 72(SP)
0x001c 00028 (./src/main.go:30) LEAQ 72(SP), BP
0x0021 00033 (./src/main.go:30) FUNCDATA$0, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0021 00033 (./src/main.go:30) FUNCDATA$1, gclocals·e226d4ae4a7cad8835311c6a4683c14f(SB)
0x0021 00033 (./src/main.go:31) MOVQ $18, ""..autotmp_1+48(SP)
0x002a 00042 (./src/main.go:31) LEAQ go.itab."".Student,"".Person(SB), AX
0x0031 00049 (./src/main.go:31) MOVQ AX, (SP)
0x0035 00053 (./src/main.go:31) LEAQ ""..autotmp_1+48(SP), AX
0x003a 00058 (./src/main.go:31) MOVQ AX, 8(SP)
0x003f 00063 (./src/main.go:31) PCDATA $0, $0
0x003f 00063 (./src/main.go:31) CALL runtime.convT2I64(SB)
0x0044 00068 (./src/main.go:31) MOVQ 24(SP), AX
0x0049 00073 (./src/main.go:31) MOVQ 16(SP), CX
0x004e 00078 (./src/main.go:33) TESTQ CX, CX
0x0051 00081 (./src/main.go:33) JEQ 87
0x0053 00083 (./src/main.go:33) MOVQ 8(CX), CX
0x0057 00087 (./src/main.go:33) MOVQ $0, ""..autotmp_2+56(SP)
0x0060 00096 (./src/main.go:33) MOVQ $0, ""..autotmp_2+64(SP)
0x0069 00105 (./src/main.go:33) MOVQ CX, ""..autotmp_2+56(SP)
0x006e 00110 (./src/main.go:33) MOVQ AX, ""..autotmp_2+64(SP)
0x0073 00115 (./src/main.go:33) LEAQ ""..autotmp_2+56(SP), AX
0x0078 00120 (./src/main.go:33) MOVQ AX, (SP)
0x007c 00124 (./src/main.go:33) MOVQ $1, 8(SP)
0x0085 00133 (./src/main.go:33) MOVQ $1, 16(SP)
0x008e 00142 (./src/main.go:33) PCDATA $0, $1
0x008e 00142 (./src/main.go:33) CALL fmt.Println(SB)
0x0093 00147 (./src/main.go:34) MOVQ 72(SP), BP
0x0098 00152 (./src/main.go:34) ADDQ $80, SP
0x009c 00156 (./src/main.go:34) RET
0x009d 00157 (./src/main.go:34) NOP
0x009d 00157 (./src/main.go:30) PCDATA $0, $-1
0x009d 00157 (./src/main.go:30) CALL runtime.morestack_noctxt(SB)
0x00a2 00162 (./src/main.go:30) JMP 0
func convT2I64(tab *itab, elem unsafe.Pointer) (i iface) {
// â¦â¦
}
go.itab."".Student,"".Person SNOPTRDATA dupok size=40
0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0010 00 00 00 00 00 00 00 00 da 9f 20 d4
rel 0+8 t=1 type."".Person+0
rel 8+8 t=1 type."".Student+0
type itab struct {
inter *interfacetype // 8åè
_type *_type // 8åè
link *itab // 8åè
hash uint32 // 4åè
bad bool // 1åè
inhash bool // 1åè
unused [2]byte // 2åè
fun [1]uintptr // variable sized // 8åè
}
func convT2I64(tab *itab, elem unsafe.Pointer) (i iface) {
t := tab._type
//...
var x unsafe.Pointer
if *(*uint64)(elem) == 0 {
x = unsafe.Pointer(&zeroVal[0])
} else {
x = mallocgc(8, t, false)
*(*uint64)(x) = *(*uint64)(elem)
}
i.tab = tab
i.data = x
return
}
type iface struct {
tab *itab
data unsafe.Pointer
}
type itab struct {
inter uintptr
_type uintptr
link uintptr
hash uint32
_ [4]byte
fun [1]uintptr
}
func main() {
var qcrao = Person(Student{age: 18})
iface := (*iface)(unsafe.Pointer(&qcrao))
fmt.Printf("iface.tab.hash = %#x\n", iface.tab.hash)
}
iface.tab.hash = 0xd4209fda
package main
import "fmt"
func main() {
var i int = 9
var f float64
f = float64(i)
fmt.Printf("%T, %v\n", f, f)
f = 10.8
a := int(f)
fmt.Printf("%T, %v\n", a, a)
// s := []int(i)
cannot convert i (type int) to type []int
package main
import "fmt"
type Student struct {
Name string
Age int
}
func main() {
var i interface{} = new(Student)
s := i.(Student)
fmt.Println(s)
}
panic: interface conversion: interface {} is *main.Student, not main.Student
func main() {
var i interface{} = new(Student)
s, ok := i.(Student)
if ok {
fmt.Println(s)
}
}
func main() {
//var i interface{} = new(Student)
//var i interface{} = (*Student)(nil)
var i interface{}
fmt.Printf("%p %v\n", &i, i)
judge(i)
}
func judge(v interface{}) {
fmt.Printf("%p %v\n", &v, v)
switch v := v.(type) {
case nil:
fmt.Printf("%p %v\n", &v, v)
fmt.Printf("nil type[%T] %v\n", v, v)
case Student:
fmt.Printf("%p %v\n", &v, v)
fmt.Printf("Student type[%T] %v\n", v, v)
case *Student:
fmt.Printf("%p %v\n", &v, v)
fmt.Printf("*Student type[%T] %v\n", v, v)
default:
fmt.Printf("%p %v\n", &v, v)
fmt.Printf("unknow\n")
}
}
type Student struct {
Name string
Age int
}
// --- var i interface{} = new(Student)
0xc4200701b0 [Name: ], [Age: 0]
0xc4200701d0 [Name: ], [Age: 0]
0xc420080020 [Name: ], [Age: 0]
*Student type[*main.Student] [Name: ], [Age: 0]
// --- var i interface{} = (*Student)(nil)
0xc42000e1d0 <nil>
0xc42000e1f0 <nil>
0xc42000c030 <nil>
*Student type[*main.Student] <nil>
// --- var i interface{}
0xc42000e1d0 <nil>
0xc42000e1e0 <nil>
0xc42000e1f0 <nil>
nil type[<nil>] <nil>
var i interface{} = new(Student)
var i interface{} = (*Student)(nil)
var i interface{}
package main
import "fmt"
type Student struct {
Name string
Age int
}
func main() {
var s = Student{
Name: "qcrao",
Age: 18,
}
fmt.Println(s)
}
{qcrao 18}
func (s Student) String() string {
return fmt.Sprintf("[Name: %s], [Age: %d]", s.Name, s.Age)
}
[Name: qcrao], [Age: 18]
func (s *Student) String() string {
return fmt.Sprintf("[Name: %s], [Age: %d]", s.Name, s.Age)
}
{qcrao 18}
fmt.Println(s)
fmt.Println(&s)
fmt.Println(&s)
package main
import "fmt"
type coder interface {
code()
run()
}
type runner interface {
run()
}
type Gopher struct {
language string
}
func (g Gopher) code() {
return
}
func (g Gopher) run() {
return
}
func main() {
var c coder = Gopher{}
var r runner
r = c
fmt.Println(c, r)
}
go tool compile -S ./src/main.go
func convI2I(inter *interfacetype, i iface) (r iface) {
tab := i.tab
if tab == nil {
return
}
if tab.inter == inter {
r.tab = tab
r.data = i.data
return
}
r.tab = getitab(inter, tab._type, false)
r.data = i.data
return
}
func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
// â¦â¦
// æ ¹æ® inter, typ 计ç®åº hash å¼
h := itabhash(inter, typ)
// look twice - once without lock, once with.
// common case will be no lock contention.
var m *itab
var locked int
for locked = 0; locked < 2; locked++ {
if locked != 0 {
lock(&ifaceLock)
}
// éååå¸è¡¨çä¸ä¸ª slot
for m = (*itab)(atomic.Loadp(unsafe.Pointer(&hash[h]))); m != nil; m = m.link {
// å¦æå¨ hash 表ä¸å·²ç»æ¾å°äº itabï¼inter å typ æéé½ç¸åï¼
if m.inter == inter && m._type == typ {
// â¦â¦
if locked != 0 {
unlock(&ifaceLock)
}
return m
}
}
}
// å¨ hash è¡¨ä¸æ²¡ææ¾å° itabï¼é£ä¹æ°çæä¸ä¸ª itab
m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*sys.PtrSize, 0, &memstats.other_sys))
m.inter = inter
m._type = typ
// æ·»å å°å
¨å±ç hash 表ä¸
additab(m, true, canfail)
unlock(&ifaceLock)
if m.bad {
return nil
}
return m
}
// æ£æ¥ _type æ¯å¦ç¬¦å interface_type å¹¶ä¸å建对åºç itab ç»æä½ å°å
¶æ¾å° hash 表ä¸
func additab(m *itab, locked, canfail bool) {
inter := m.inter
typ := m._type
x := typ.uncommon()
// both inter and typ have method sorted by name,
// and interface names are unique,
// so can iterate over both in lock step;
// the loop is O(ni+nt) not O(ni*nt).
//
// inter å typ çæ¹æ³é½ææ¹æ³åç§°è¿è¡äºæåº
// 并䏿¹æ³å齿¯å¯ä¸çãæä»¥å¾ªç¯çæ¬¡æ°æ¯åºå®ç
// åªç¨å¾ªç¯ O(ni+nt)ï¼èé O(ni*nt)
ni := len(inter.mhdr)
nt := int(x.mcount)
xmhdr := (*[1 << 16]method)(add(unsafe.Pointer(x), uintptr(x.moff)))[:nt:nt]
j := 0
for k := 0; k < ni; k++ {
i := &inter.mhdr[k]
itype := inter.typ.typeOff(i.ityp)
name := inter.typ.nameOff(i.name)
iname := name.name()
ipkg := name.pkgPath()
if ipkg == "" {
ipkg = inter.pkgpath.name()
}
for ; j < nt; j++ {
t := &xmhdr[j]
tname := typ.nameOff(t.name)
// æ£æ¥æ¹æ³å忝å¦ä¸è´
if typ.typeOff(t.mtyp) == itype && tname.name() == iname {
pkgPath := tname.pkgPath()
if pkgPath == "" {
pkgPath = typ.nameOff(x.pkgpath).name()
}
if tname.isExported() || pkgPath == ipkg {
if m != nil {
// è·å彿°å°åï¼å¹¶å å
¥å°itab.funæ°ç»ä¸
ifn := typ.textOff(t.ifn)
*(*unsafe.Pointer)(add(unsafe.Pointer(&m.fun[0]), uintptr(k)*sys.PtrSize)) = ifn
}
goto nextimethod
}
}
}
// â¦â¦
m.bad = true
break
nextimethod:
}
if !locked {
throw("invalid itab locking")
}
// è®¡ç® hash å¼
h := itabhash(inter, typ)
// å å°Hash Sloté¾è¡¨ä¸
m.link = hash[h]
m.inhash = true
atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))
}
func itabhash(inter *interfacetype, typ *_type) uint32 {
h := inter.typ.hash
h += 17 * typ.hash
return h % hashSize
}
package main
import "fmt"
func main() {
qcrao := Student{age: 18}
whatJob(&qcrao)
growUp(&qcrao)
fmt.Println(qcrao)
stefno := Programmer{age: 100}
whatJob(stefno)
growUp(stefno)
fmt.Println(stefno)
}
func whatJob(p Person) {
p.job()
}
func growUp(p Person) {
p.growUp()
}
type Person interface {
job()
growUp()
}
type Student struct {
age int
}
func (p Student) job() {
fmt.Println("I am a student.")
return
}
func (p *Student) growUp() {
p.age += 1
return
}
type Programmer struct {
age int
}
func (p Programmer) job() {
fmt.Println("I am a programmer.")
return
}
func (p Programmer) growUp() {
// ç¨åºåèå¾å¤ªå¿« ^_^
p.age += 10
return
}
job()
growUp()
func whatJob(p Person)
func growUp(p Person)
I am a student.
{19}
I am a programmer.
{100}
class Shape
{
public:
// 纯è彿°
virtual double getArea() = 0;
private:
string name; // åç§°
};};
设计æ½è±¡ç±»çç®çï¼æ¯ä¸ºäºç»å ¶ä»ç±»æä¾ä¸ä¸ªå¯ä»¥ç»§æ¿çéå½çåºç±»ãæ½è±¡ç±»ä¸è½è¢«ç¨äºå®ä¾å对象ï¼å®åªè½ä½ä¸ºæ¥å£ä½¿ç¨ã
æ´¾çç±»éè¦æç¡®å°å£°æå®ç»§æ¿èªåºç±»ï¼å¹¶ä¸éè¦å®ç°åºç±»ä¸ææç纯è彿°ã
C++ å®ä¹æ¥å£çæ¹å¼ç§°ä¸ºâä¾µå ¥å¼âï¼è Go éç¨çæ¯ âéä¾µå ¥å¼âï¼ä¸éè¦æ¾å¼å£°æï¼åªéè¦å®ç°æ¥å£å®ä¹ç彿°ï¼ç¼è¯å¨èªå¨ä¼è¯å«ã
C++ å Go å¨å®ä¹æ¥å£æ¹å¼ä¸çä¸åï¼ä¹å¯¼è´äºåºå±å®ç°ä¸çä¸åãC++ éè¿è彿°è¡¨æ¥å®ç°åºç±»è°ç¨æ´¾çç±»ç彿°ï¼è Go éè¿ itab
 ä¸ç fun
åæ®µæ¥å®ç°æ¥å£åéè°ç¨å®ä½ç±»åç彿°ãC++ ä¸çè彿°è¡¨æ¯å¨ç¼è¯æçæçï¼è Go ç itab
 ä¸ç fun
åæ®µæ¯å¨è¿è¡æé´å¨æçæçãåå å¨äºï¼Go ä¸å®ä½ç±»åå¯è½ä¼æ æä¸å®ç° N 夿¥å£ï¼å¾å¤æ¥å£å¹¶ä¸æ¯æ¬æ¥éè¦çï¼æä»¥ä¸è½ä¸ºç±»åå®ç°çæææ¥å£é½çæä¸ä¸ª itab
ï¼ è¿ä¹æ¯âéä¾µå
¥å¼â带æ¥çå½±åï¼è¿å¨ C++ 䏿¯ä¸åå¨çï¼å 为派çéè¦æ¾ç¤ºå£°æå®ç»§æ¿èªåªä¸ªåºç±»ã
åèèµæ
ãå å«åå°ãæ¥å£çæºç åæãhttps://zhuanlan.zhihu.com/p/27055513
ãè彿°è¡¨åC++çåºå«ãhttps://mp.weixin.qq.com/s/jU9HeR1tOyh-ME5iEYM5-Q
ãå ·ä½ç±»å忥å£èµå¼ãhttps://tiancaiamao.gitbooks.io/go-internals/content/zh/07.2.html
ãGoå¤è¯»ç¾¤ç讨论ãhttps://github.com/developer-learning/reading-go/blob/master/content/discuss/2018-08-30-understanding-go-interfaces.md
ãå»éªå³° é¸åç±»åãhttps://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431865288798deef438d865e4c2985acff7e9fad15e3000
ãå¼ç±»ååæéç±»åï¼ifaceæºç ãhttps://www.jianshu.com/p/5f8ecbe4f6af
ãæ»ä½è¯´æitabççææ¹å¼ãä½ç¨ãhttp://www.codeceo.com/article/go-interface.html
ãconvç³»å彿°çä½ç¨ãhttps://blog.****.net/zhonglinzhang/article/details/85772336
ãconvI2I itabä½ç¨ãhttps://www.jianshu.com/p/a5e99b1d50b1
ãinterface æºç 解读 å¾ä¸é å å«åå°ãhttp://wudaijun.com/2018/01/go-interface-implement/
ãwhat why howæè·¯æ¥åinterfaceãhttp://legendtkl.com/2017/06/12/understanding-golang-interface/
ãææ±ç¼åæï¼ä¸éãhttp://legendtkl.com/2017/07/01/golang-interface-implement/
ã第ä¸å¹ å¾å¯ä»¥åè gdbè°è¯ãhttps://www.do1618.com/archives/797/golang-interface%E5%88%86%E6%9E%90/
ãç±»å转æ¢åæè¨ãhttps://my.oschina.net/goal/blog/194308
ãinterface å nilãhttps://my.oschina.net/goal/blog/194233
ã彿°åæ¹æ³ãhttps://www.jianshu.com/p/5376e15966b3
ãåå°ãhttps://flycode.co/archives/267357
ãæ¥å£ç¹ç¹å表ãhttps://segmentfault.com/a/1190000011451232
ãinterface å ¨é¢ä»ç»ï¼å å«C++对æ¯ãhttps://www.jianshu.com/p/b38b1719636e
ãGoååäºç« ç» interfaceãhttps://github.com/ffhelicopter/Go42/blob/master/content/42_19_interface.md
ã对Goæ¥å£çåé©³ï¼æè¯´å°æ¥å£çå®ä¹ãhttp://blog.zhaojie.me/2013/04/why-i-dont-like-go-style-interface-or-structural-typing.html
ãgopher æ¥å£ãhttp://fuxiaohei.me/2017/4/22/gopherchina-2017.html
ãè¯æ è¿ä¸éãhttps://mp.weixin.qq.com/s/tBg8D1qXHqBr3r7oRt6iGA
ãinfoQ æç« ãhttps://www.infoq.cn/article/go-interface-talk
ãGoæ¥å£è¯¦è§£ãhttps://zhuanlan.zhihu.com/p/27055513
ãGo interfaceãhttps://sanyuesha.com/2017/07/22/how-to-understand-go-interface/
ãgetitabæºç 说æãhttps://www.twblogs.net/a/5c245d59bd9eee16b3db561d
ãæµ æ¾ææãhttps://yami.io/golang-interface/
ãgolang ioå çå¦ç¨ãhttps://www.jianshu.com/p/8c33f7c84509
ãæ¢ç´¢C++ä¸Goçæ¥å£åºå±å®ç°ãhttps://www.jianshu.com/p/073c09a05da7 https://github.com/teh-cmc/go-internals/blob/master/chapter2_interfaces/README.md
ãæ±ç¼å±é¢ãhttp://xargin.com/go-and-interface/
ãæå¾ãhttps://i6448038.github.io/2018/10/01/Golang-interface/
ãå¾ãhttps://mp.weixin.qq.com/s/px9BRQrTCLX6BbvXJbysCA
ãè±æå¼æºä¹¦ãhttps://github.com/cch123/go-internals/blob/master/chapter2_interfaces/README.md
ãæ¹å¤§çç¿»è¯ãhttp://xargin.com/go-and-interface/