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