深度解密Go语言之关于 interface 的 10 个问题 |
您所在的位置:网站首页 › 未来一月黄金价格走势 › 深度解密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 å¼é½æ¹åäºã å®é ä¸ï¼å½ç±»ååæ¹æ³çæ¥æ¶è ç±»åä¸åæ¶ï¼å ¶å®æ¯ç¼è¯å¨å¨èååäºä¸äºå·¥ä½ï¼ç¨ä¸ä¸ªè¡¨æ ¼æ¥åç°ï¼ - å¼æ¥æ¶è æéæ¥æ¶è å¼ç±»åè°ç¨è æ¹æ³ä¼ä½¿ç¨è°ç¨è çä¸ä¸ªå¯æ¬ï¼ç±»ä¼¼äºâä¼ å¼â 使ç¨å¼çå¼ç¨æ¥è°ç¨æ¹æ³ï¼ä¸ä¾ä¸ï¼qcrao.growUp() å®é ä¸æ¯Â (&qcrao).growUp() æéç±»åè°ç¨è æé被解å¼ç¨ä¸ºå¼ï¼ä¸ä¾ä¸ï¼stefno.howOld() å®é ä¸æ¯Â (*stefno).howOld() å®é ä¸ä¹æ¯âä¼ å¼âï¼æ¹æ³éçæä½ä¼å½±åå°è°ç¨è ï¼ç±»ä¼¼äºæéä¼ åï¼æ·è´äºä¸ä»½æé å¼æ¥æ¶è åæéæ¥æ¶èåé¢è¯´è¿ï¼ä¸ç®¡æ¥æ¶è ç±»åæ¯å¼ç±»åè¿æ¯æéç±»åï¼é½å¯ä»¥éè¿å¼ç±»åææéç±»åè°ç¨ï¼è¿éé¢å®é ä¸éè¿è¯æ³ç³èµ·ä½ç¨çã å 说ç»è®ºï¼å®ç°äºæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ï¼ç¸å½äºèªå¨å®ç°äºæ¥æ¶è æ¯æéç±»åçæ¹æ³ï¼èå®ç°äºæ¥æ¶è æ¯æéç±»åçæ¹æ³ï¼ä¸ä¼èªå¨çæ对åºæ¥æ¶è æ¯å¼ç±»åçæ¹æ³ã æ¥çä¸ä¸ªä¾åï¼å°±ä¼å®å ¨æç½ï¼ ä¸è¿°ä»£ç éå®ä¹äºä¸ä¸ªæ¥å£Â 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 æé è°ç¨Â runtime.convT2I64(SB) çåæ° æ们æ¥çä¸è¿ä¸ªå½æ°çåæ°å½¢å¼ï¼ 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 è°ç¨Â runtime.convT2I64(SB) å ·ä½çä¸ä»£ç ï¼ âè¿å代ç æ¯è¾ç®åï¼æ tab èµç»äºÂ iface ç tab å段ï¼data é¨ååæ¯å¨å ä¸ç³è¯·äºä¸åå åï¼ç¶åå°Â elem æåç 18 æ·è´è¿å»ãè¿æ · iface å°±ç»è£ 好äºã æ±ç¼è¡æ° æä½ 17 æ i.tab èµç»Â CX 18 æ i.data èµç»Â AX 19-21 æ£æµÂ i.tab æ¯å¦æ¯ nilï¼å¦æä¸æ¯çè¯ï¼æ CX ç§»å¨ 8 个åèï¼ä¹å°±æ¯æ itab ç _type å段èµç»äº CXï¼è¿ä¹æ¯æ¥å£çå®ä½ç±»åï¼æç»è¦ä½ä¸ºÂ fmt.Println å½æ°çåæ° åé¢ï¼å°±æ¯è°ç¨Â 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 åæ¶éè¦æ¥å£çç±»ååå®ä½çç±»åã ->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: , true false c: *main.Gopher, 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 } 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 0xc42000e1f0 0xc42000c030 *Student type[*main.Student] // --- var i interface{} 0xc42000e1d0 0xc42000e1e0 0xc42000e1f0 nil type[] 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 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |