Type Inference vs. Static/Dynamic Typing
Herb Sutter "Type Inference vs. Static/Dynamic Typing"ã®é©å½ãªè¨³ã§ãã
var/autoã®ä½¿ãæ¹ã«é¢ãããã³ãã«ãªããã¨æã£ãããvar/autoã¨åçåä»ããæ··åãã¡ãã ãã ããã¨ããã話ãæ¬é¦ã®ããã°çéã§ã¯ãã®æã®æ··åã¯è¦ãªãã£ãæ°ããããã©ã
â¦ãªãã§ããããvariant/anyã®è©±ã«ãªãã®ããã¾ãã¡åãããªããã§ããã
ã¡ããã©Jeff Atoodã"a nice piece on why type inference is convenient"ã¨ããè¨äºãæ¸ãã¦ããããã®ä¸ã§å½¼ã¯C#ã®ãµã³ãã«ã使ã£ã¦æ¬¡ã®ããã«æ¸ãã¦ããï¼
ãããªã³ã¼ãã
StringBuilder sb = new StringBuilder(256); UTF8Encoding e = new UTF8Encoding(); MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();ãããªé¢¨ã«
var sb = new StringBuilder(256); var e = new UTF8Encoding(); var md5 = new MD5CryptoServiceProvider();æ¸ãç´ããã¨ãã§ãããªãã¦ãã¾ã£ãã身éããã¡ãã£ããã
ããã¯åçåä»ããããªããæ¬è³ªçã«ã¯ããC#ã¯ãã¾ã ã«ã¨ã¦ãå¼·åãªéçåä»ãè¨èªã ãããã®ã»ã¨ãã©ã¯ã³ã³ãã¤ã©ã®ããªãã¯ã§ããå¯è½ãªéãéçåä»ãã§ãå¿ è¦ãªãåçåä»ãã§ãã¨ããä¸çã¸ã®å°ããªä¸æ©ã ã
次ã®ãããªäºæã®éã«æ確ãªåºå¥ãã¤ãããã¨ã«ã¯ä¾¡å¤ãããï¼
- ããããè¨èªã§ããªããã§ãããããªåæ¨è«
- éçåä»ã vs. åçåä»ãï¼ããã¯å®ç§ã«ç´äº¤ãããã®ã ããåæ¨è«ã¨æ··åããããã¦ãã
- å¼·ãåä»ã vs. å¼±ãåä»ãï¼ããã¯ã»ã¨ãã©ç´äº¤ããï¼ä¾ãã°ãCã¯ãã¹ã¦ã®å¤æ°ãéçã«ç¥ãããå®éã®åãæã£ã¦ããããéçåä»ãã§ãããããã£ã¹ãã®ããã«å¼±ãåä»ãè¨èªã§ãããï¼
ä¸è¿°ã®è¨äºã§ãJeffã¯åæ¨è«ã¨åçåä»ããæ確ã«åãã¦ãããå½¼ã¯åæ¨è«ãåçåä»ãã¸ã®å°ããªä¸æ©ã§ããã¨ããèªèª¬ãé²ãã¦ããããã®ä¸»å¼µã¯ãæä½çã«ã¯ååçã«çã§ãããã®ã®ãæ®å¿µãªããèªè ã®ä¸é¨ã誤èªãããå¯è½æ§ããããã¤ã¾ããåæ¨è«ã¯åçæ§è³ªã¨ä½ããã®é¢ä¿ããããã¨ãå®éã«ã¯ããã§ã¯ãªãã®ã«ã
åæ¨è«
ä¸è¨ã®C#ã次ã®æ¨æºC++ï¼C++0x, ããã¯ä»¥ä¸ã§è¿°ã¹ãï¼ãªã©å¤ãã®è¨èªã§åæ¨è«æ©æ§ãæä¾ããã¦ãããC++0xã¯autoãã¼ã¯ã¼ããåå©ç¨ãããã¨ã§ãããå®ç¾ãã¦ãããä¾ãã°ãmap
map<int,list<string>>::iterator i = m.begin(); // ä»æ¥ã®C++ã§ã¯åãå¿ è¦ï¼C++0xã§ã許ãããï¼ auto i = m.begin(); // C++0xã§ã¯åã¯æ¨è«ããã
ãã³ã³ãã¤ã©ãããåã¯ãã®åãä½ã ãæ¢ã«ç¥ã£ã¦ããããã«ããªãã¾ã俺ã«ç¹°ãè¿ããããã¨ãããã ï¼ãããè¨ã£ããã¨ãä½åº¦ãããã§ãããï¼IDEã§ãããå¼ã®ä¸ã«ã«ã¼ã½ã«ãã®ããããã®åãæãã¦ããããã
C++0xã§ã¯ãããããªäºãè¨ããªãã¦ãæ¸ããããã¯ããªã便å©ã ãåãèªåã®æã§æ¸ããããªãããããã¯æ¸ããã¨ãã§ããªãããã«ãªã£ã¦ãã¦ããã®ã ããããã®ãã¨ã¯æ¥å¢ãã«éè¦ã«ãªã£ã¦ãã¦ãããã¨ããã®ã次ã®ãããªåãæ±ããã¨ãå¢ãã¦ãã¦ããããã ï¼
- ããè¤éãªååã®å
- ååã®ãªãï¼ã¾ãã¯ååãç¥ããã¨ãé£ããï¼å
- å¤ãã®å ´åå©ä¾¿æ§ã®é½åã§å°å ¥ãããéæ¥çãªå
ç¹ã«ãC++0xã®ã©ã ãé¢æ°ãçæããé¢æ°ãªãã¸ã§ã¯ããèãã¦ã¿ãããä¸è¬çã«ãã®åãæ¸ãåºãã®ã¯å°é£ã ãã ããautoã使ããã«ãã®é¢æ°ãªãã¸ã§ã¯ããä¿æããããªããéæ¥çãªåã使ããããå¾ãªãï¼
function<void(void)> f = [] { DoSomething(); }; // ã©ããã¼ã§ä¿æããï¼éæ¥çãªåãå¿ è¦ auto f = [] { DoSomething(); }; // åãæ¨è«ãã¦ç´æ¥æç¸
ãã®å¾ã®æ¹ã®æ¸ãæ¹ã¯ãé¢æ°ãã¤ã³ã¿ãç¨ããCè¨èªã®ç価ãªã³ã¼ãããå¹ççã§ããç¹ã«ã注ç®ããªããªãC++ã¯ããããã³ã¼ããã¤ã³ã©ã¤ã³åããã¦ãããããã ã詳ããã¯Scott Meyersã®"Effective STL"第46é ã®ãé¢æ°ãããé¢æ°ãªãã¸ã§ã¯ãã使ããããè¦ã¦æ¬²ããããã¤ã¾ãï¼ç´æã«åãã¦ï¼ãã®ã»ããå¹ççãªã®ã ã
ãã¦ãautoãvarã®ç´ æ´ãããã«çåã®ä½å°ã¯ãªãã¨ã¯ããããããã«ãäºç´°ãªå¶éããããã¨ãããæ£ç¢ºãªåãå¿ è¦ãªããã§ãªããä»ã®å¤æå¯è½ãªåã欲ããå ´åãããã ï¼
map<int,list<string>>::const_iterator ci = m.begin(); // ciã®åã¯map<int,...> auto i = m.begin(); // iã®åã¯map<int,...> Widget* w = new Widget(); // wã®åã¯Widget* const Widget* cw = new Widget(); // cwã®åã¯const Widget* WidgetBase* wb = new Widget(); // wbã®åã¯WidgetBase* shared_ptr<Widget> spw(new Widget()); // spwã®åã¯shared_ptr<...> auto w = new Widget(); // wã®åã¯Widget*
ã¤ã¾ãC++0xã®autoã¯ï¼C#ã®varã¨åæ§ã«ï¼ãã£ã¨ãæ確ãªåãå¾ããã¨ããã§ããªããã¨ã¯ãããããã§ã»ã¨ãã©ã®ã±ã¼ã¹ã¯ã«ãã¼ã§ããã
ä¸è¨ã®ä¾ã®ãã¹ã¦ã«ã¤ãã¦æ³¨æãã¦ããã¦æ¬²ããéè¦ãªç¹ã¯ãåãã©ã綴ããã¨ããã¹ã¦ã®å¤æ°ã¯æ確ã§ãããã¾ãæ§ããªããæ¢ç¥ã§ãäºæ¸¬å¯è½ãªéçãªåãæã¤ã¨ãããã¨ã ãC++0xã®autoãC#ã®varã¯ç´ç²ã«è¨æ³ä¸ã®ä¾¿å®ã§ãã£ã¦ãæã ãèªåã§ååã綴ãå¿ è¦æ§ããæã£ã¦ãããããããå¤æ°ããã£ãä¸ã¤ã®åºå®ãããéçãªåãæã¤ã¨ãããã¨ã¯å¤ãããªãã
éçåä»ãã¨åçåä»ã
ä¸è¨ã®å¼ç¨ã§Jeffãæ£ããææãã¦ããããã«ãããã¯åçåä»ãã§ã¯ãªããåçåä»ãã¨ã¯ãåãå¤æ°ããã®çåæéã®å¥ã®æç¹ã«ããã¦ç°ãªãå®éã®åãæã¤ãã¨ã許ããã¨ãããã¨ã ãæ®å¿µãªããå½¼ã¯ããç¶ãã¦ãã¾ã£ã¦ããããããã¯èªè ã«å¥ã®ãã¨ãæ³èµ·ããã¨ãããã¹ãå¼ãèµ·ãããããªãï¼
æé»çãªå¤æ°ã®åä»ãã¯ãããåçãªåä»ãè¨èªã¸ã¨è³ãå ¥éç¨ã®éº»è¬ã ãã¨ããè¨ãåºã人ãããã ããã
åãè¨äºã®ä¸ã§Jeffãæ¸ãã¦ãããã¨ã¯æ£ãããããå½¼ãä½ã«ã¤ãã¦èªã£ã¦ããã®ãç解ãã¦ãããã¨ã¯åãã£ã¦ãããããããããã¯ããããªããã¦ãããæ¹ãè¯ãï¼åæ¨è«ã¯åçåä»ãã¨ã¯é¢ä¿ãªãã
Jeffãã¡ããã¨æ³¨æãã¦ãããåæ¨è«ã¯ããã¤ãåãåçåä»ãè¨èªã§ãã£ã¦ããããã«å¤æ°ã宣è¨ã§ããããã«ããã ãã®ãã¨ã ãã¨ãï¼ãã®ãã¹ããããåã«ãç§ã¯"Lambda the Ultimate"ã§ãåãæ··ä¹±ã«åºã¥ããã³ã¡ã³ããç®ã«ãããå°ãªãã¨ãã³ã¡ã³ãããä¸äººã¯ãããã¯éçåä»ãè¨èªã¸ã®å
¥éç¨éº»è¬ã ã¨ã¿ãªããã¨ãã§ããã¨è¿°ã¹ã¦ããããªããªããéçåä»ããæ¾æ£ããã«è¨è¿°ä¸ã®ä¾¿å®ãå¾ããã¨ãå¯è½ã ããã ãï¼
Bjarneã®ç¨èªéããå¼ç¨ããã¨ï¼
- åçåä»ã
- ãªãã¸ã§ã¯ãã®åãå®è¡æã«æ±ºå®ãããï¼ä¾ãã°ãdynamic_castãtypeidãç¨ãããã¨ãmost-derived type(訳注ï¼æå¾ã«æ´¾çãããå)ã¨ãã
- éçåä»ã
- ãªãã¸ã§ã¯ãã®åããã®å®£è¨ãå ã«ã³ã³ãã¤ã©ã«ç¥ããããåçåä»ããåç §ã
å ã»ã©ã®C++ã®ä¾ã«æ»ããããã®ä¾ã§ã¯å¤æ°ã®åçåã¨éçåã®éãã示ãã¦ããã
WidgetBase* wb = new Widget(); // wbã®éçåã¯WidgetBase* if( dynamic_cast<Widget*>(wb ) ){ ... } // ãã£ã¹ãã¯æåããï¼wbã®åçåã¯Widget*
å¤æ°ã®éçãªåã¯ãããããµãã¼ããã¦ããã¤ã³ã¿ãã§ã¼ã¹ãè¿°ã¹ã¦ãããã ãããã®ã±ã¼ã¹ã§ã¯ãwbã¯WidgetBaseã®ã¡ã³ãããã¢ã¯ã»ã¹ããã¦ãããªããå¤æ°ã®åçãªåã¯ãã¾ãã«ãã®æç¹ã§ãã®å¤æ°ãæãã¦ãããªãã¸ã§ã¯ãã®åã§ããã
ããããåçã«åä»ããããè¨èªã§ã¯ãå¤æ°ã¯éçãªåãæãããæèãããã¨ããªããå¤ãã®åçè¨èªã§ã¯ãå¤æ°ã宣è¨ããå¿ è¦ãããªããä¾ãã°ï¼
x = 10; // xã®åã¯int x = "hello, world"; // xã®åã¯str
Boostã®variantã¨any
è¨èªã¨ãã¦éçã«åä»ããããã¾ã¾ã®C++ã§åæ§ã®å¹æãå¾ãã«ã¯ãäºéãã®æ¹æ³ããããä¸ã¤ç®ã¯ãBoostã®variantã ï¼
// C++ using Boost variant< int, string > x; // 許ãããåã宣è¨ãã x = 42; // x 㯠int ãä¿æãã x = "hello, world"; // x 㯠string ãä¿æãã x = new Widget(); // int ã§ã string ã§ããªãã®ã§ã¨ã©ã¼
unionã¨ã¯ç°ãªããvariantã¯åºæ¬çã«ãããã種é¡ã®åãå«ãããã¨ãã§ããããåã¯åãã£ã¦å®ç¾©ããã¦ããå¿
è¦ãããããªã¼ãã¼ãã¼ãã®è§£æ±ºãã·ãã¥ã¬ã¼ããããã¨ãå¯è½ã§ãboost::apply_visitorãç¨ãããããã¯éçã«ï¼ã³ã³ãã¤ã«æã«ï¼ãã§ãã¯ãããã
äºã¤ç®ã¯Boost anyã ï¼
// C++ using Boost any x; x = 42; // x 㯠int ãä¿æãã x = "hello, world"; // x 㯠string ãä¿æãã x = new Widget(); // x 㯠Widget* ãä¿æãã
ããã¾ãunionã¨ã¯ç°ãªããããããåãanyã«å«ãããã¨ãã§ãããã¨ãããvariantoã¨ã¯ç°ãªããanyã¯åãã£ã¦åãå®ç¾©ãããã¨ãå¼·è¦ããªãï¼ãã¦ãããªãï¼ããã®è¯ãæªãã¯ãåãåä»ããã©ãã¾ã§ç·©åããããã«å¯ã£ã¦æ±ºã¾ããã¾ããanyã¯ãªã¼ãã¼ãã¼ãã®è§£æ±ºãã·ãã¥ã¬ã¼ãããæ段ããªããä¿æãããªãã¸ã§ã¯ãã®ããã«ãã¼ãé åã常ã«å¿ è¦ã¨ããã
é¢ç½ããã¨ã«ããã®ãã¨ã¯C++ãããã«å·§ã¿ã«ããã£ããã¨ï¼ãããå¹çãç½®ãå»ãã«ããã«ï¼ãå¯è½ãªéãéçåä»ãã§ãå¿ è¦ãªãåçåä»ãã§ãã¸ã®éãé²ãã§ãããã示ãã¦ããã
次ã®ãããªã±ã¼ã¹ã§ã¯variantã使ããï¼
- æå®ããåã®çµã®ããããã²ã¨ã¤ã®å¤ãä¿æãããªãã¸ã§ã¯ãã欲ããã¨ã
- ãªã¼ãã¼ãã¼ãã®è§£æ±ºãã³ã³ãã¤ã«æã«ãã§ãã¯ãããã¨ã
- å¯è½ãªå ´åã¯ã¹ã¿ãã¯é åã使ãï¼åçã¢ãã±ã¼ã·ã§ã³ã®ãªã¼ãã¼ããããåé¿ããï¼ãã¨ã§å¹ççã«ãããã¨ã
- æ£ç¢ºã«æ£ããåã使ããªãã£ãå ´åã«æããããªã¨ã©ã¼ã¡ãã»ã¼ã¸ãåºãã¦ããã¦æ§ããªãã¨ã
次ã®ãããªã±ã¼ã¹ã§ã¯anyã使ããï¼
- ä»®æ³çã«ããããã(any)ãåã®å¤ãä¿æã§ãããªãã¸ã§ã¯ãã使ã£ã¦ãæè»æ§ãæããããã¨ã
- any_castã®æè»æ§ãå½ã¦ã«ãããã¨ã
- swapã«å¯¾ãã¦ä¾å¤ãéåºããªãä¿è¨¼ã欲ããã¨ã