è¿æ¬¡æç« ä¾ç¶å¾é¿ï¼åºæ¬ä¸æ¶µçäºÂ 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.csdn.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/