Rustã§éçºãããŠããäž»ãªè£œåã¯ãMozillaã§ãéçºãããŠããæ°ããServo Webãšã³ãžã³ã§ãã 2013幎ãSamsung Electronics Corporationã¯RustãšServoã®éçºã«åå ãããã®ç©æ¥µçãªåå ã«ãããServoãšã³ãžã³ã³ãŒããARMã¢ãŒããã¯ãã£ã«ç§»æ€ãããŸããã ITæ¥çã®ãã®ãããªçå£ãªãã¬ãŒã€ãŒã«ãããã®èšèªã®ãµããŒãã¯åã°ãã«ã¯ããããããã®ç©æ¥µçãªéçºãšæ¹åã«åžæãäžããŠããŸãã
Rustèšèªã¯ãã·ã¹ãã ããã³ãããã¯ãŒã¯éçºè ãCããã³C ++ã§ããã©ãŒãã³ã¹ãéèŠãªè·å Žã§å€ãã®ã³ãŒããèšè¿°ããå¿ èŠã®ããéçºè ã«å¥œãŸããŸãã
- Rustã¯å®å šãªã¢ããªã±ãŒã·ã§ã³ã®éçºã«éç¹ã眮ããŠããŸãã ããã«ã¯ãã¡ã¢ãªã䜿çšããå®å šãªäœæ¥ãå«ãŸããŸããnullãã€ã³ã¿ãŒãååšããªãããšãåæåãããŠããªãå€æ°ããã³åæåãããŠããªãå€æ°ã®äœ¿çšãå¶åŸ¡ããããšã å ±æç¶æ ãè€æ°ã®ã¿ã¹ã¯ãšå ±æããããšã¯äžå¯èœã§ãã ãã€ã³ã¿ã®å¯¿åœã®éçåæã
- Rustã¯ã䞊åã¢ããªã±ãŒã·ã§ã³ã®éçºã«éç¹ã眮ããŠããŸãã ã©ã€ãïŒã°ãªãŒã³ïŒãããŒãéä¿¡ãããããŒã¿ãã³ããŒããªãéåæã¡ãã»ãŒãžã³ã°ãã¹ã¿ãã¯ãããŒã«ã«ã¿ã¹ã¯ããŒãããŸãã¯ã¿ã¹ã¯éã§å ±æãããããŒãå ã®ãªããžã§ã¯ãã®å Žæãéžæããæ©èœã®ãµããŒããå®è£ ããŸãã
- Rustã¯ãé床ãšã¡ã¢ãªå¹çã®é«ãã¢ããªã±ãŒã·ã§ã³ã®éçºã«éç¹ã眮ããŠããŸãã LLVMãããã¯ãšã³ããšããŠäœ¿çšãããšãã¢ããªã±ãŒã·ã§ã³ããã€ãã£ãã³ãŒãã«ã³ã³ãã€ã«ã§ããCã³ãŒããšããåãããããã®ã·ã³ãã«ãªã€ã³ã¿ãŒãã§ã€ã¹ã«ãããæ¢åã®é«æ§èœã©ã€ãã©ãªãç°¡åã«äœ¿çšã§ããŸãã
- Rustã¯ãã¯ãã¹ãã©ãããã©ãŒã ã¢ããªã±ãŒã·ã§ã³ã®éçºã«éç¹ã眮ããŠããŸãã ã³ã³ãã€ã©ã¯WindowsãLinuxãããã³Mac OS Xãã©ãããã©ãŒã ã§å ¬åŒã«ãµããŒããããŠãããFreeBSDãªã©ã®ä»ã®* NIXãã©ãããã©ãŒã ã«ãããŒãããããŸãã ããã€ãã®ããã»ããµã¢ãŒããã¯ãã£ããµããŒããããŠããŸãïŒi386ãx64ãããã³ARMã
- Rustã䜿çšãããšããªããžã§ã¯ãæåãæ©èœãã¢ã¯ã¿ãŒããŒã¹ãåœä»€åãªã©ã®ããŸããŸãªã¹ã¿ã€ã«ã§èšè¿°ã§ããŸãã
- Rustã¯ãGDBãValgrindãInstrumentsãªã©ã®æ¢åã®ãããã°ããŒã«ããµããŒãããŠããŸãã
察象èªè
æåã«ãå€æ°å®£èšã§å§ãŸããã¡ã¢ãªã¢ãã«ã®æ©èœãšæ©èœã§çµããéåžžã«åºæ¬çãªããšããèšèªã調ã¹ãå ¥éèšäºãæžãããšãèšç»ããŸããã äžæ¹ã§ããã®ãããªã¢ãããŒãã¯ãå¯èœãªéãå€ãã®ã¿ãŒã²ãããªãŒãã£ãšã³ã¹ã«ãªãŒãããããšãå¯èœã«ããŸã;äžæ¹ãåæ§ã®ã³ã³ãã³ããå«ãèšäºã¯ãC ++ãJavaãªã©ã®èšèªã§ã®äœæ¥çµéšã®ãã人ã«ãšã£ãŠã¯é¢çœããªããã¡ã€ã³ã®è©³çŽ°ãªåæãèš±å¯ããŸããRustã®æ©èœãã€ãŸããŸãã«ãããé åçã§ãã
ãããã£ãŠãå€æ°ãã«ãŒããé¢æ°ãã¯ããŒãžã£ãŒãããã³ã³ãŒãããæãããªãã®ä»ã®ãã¹ãŠã®äœæãªã©ã®åºæ¬çãªããšã詳现ã«èª¬æããªãããšã«ããŸããã Rustã®äž»ãªæ©èœãåæããéçšã§ãå®å šã«ã¯æããã§ã¯ãªãæ©èœã®å€§éšåãå¿ èŠã«å¿ããŠèª¬æãããŸãã ãã®çµæããã®èšäºã§ã¯ããã®èšèªã®3ã€ã®äž»èŠæ©èœã®ãã¡ã®2ã€ãã€ãŸãã¡ã¢ãªã®å®å šãªæäœãšäžŠåã¢ããªã±ãŒã·ã§ã³ã®äœæã«ã€ããŠèª¬æããŸãã æ®å¿µãªããããã®èšäºã®å·çæç¹ã§ã¯ããããã¯ãŒã¯ãµãã·ã¹ãã ã¯æŽ»çºã«éçºãããŠããããããã®èšäºã§ã®äœæ¥ã®èª¬æã¯ãŸã£ããç¡æå³ã§ããã
çšèª
æŠããŠãããã¯ãã·ã¢èªã®Rustã«é¢ãã2ã€ãŸãã¯3ã€ã®å©çšå¯èœãªèšäºã®1ã€ã§ããããã確ç«ããããã·ã¢èªã®çšèªã¯ãªããä»ã®ããã°ã©ãã³ã°èšèªã§ãã§ã«ããç¥ãããŠããæãé©åãªåçç©ãæ¡çšããå¿ èŠããããŸãã è±èªã®ããã¥ã¡ã³ããèšäºãããã«èªã¿ãããããããã«ããã·ã¢èªã®çšèªãåããŠç»å Žãããšãã¯ãè±èªã§ã®åçç©ãæ¬åŒ§å ã«ç€ºãããŠããŸãã
ã»ãšãã©ã®åé¡ã¯ãããã¯ã¹ãšãã€ã³ã¿ãŒãšããçšèªãåå ã§çºçããŸããã BoxãšPointerã®ããããã£ã¯ãC ++ã®ã¹ããŒããã€ã³ã¿ãŒãæãããé£æ³ãããã®ã§ãããã€ã³ã¿ãŒããšããçšèªã䜿çšããããšã«ããŸããã ãããã£ãŠãææããã¯ã¹ã¯äžæã®ãã€ã³ã¿ãŒã«ãåçšãã€ã³ã¿ãŒã¯äžæãã€ã³ã¿ãŒã«å€ãããŸããã
ã¡ã¢ãªãæäœãã
ã¡ã¢ãªã§ã®äœæ¥ã®ååã¯ããã®èšèªãã¡ã¢ãªãžã®ãã«ã¢ã¯ã»ã¹ãæã€èšèªïŒC ++ãªã©ïŒãšGCããã¡ã¢ãªãå®å šã«å¶åŸ¡ããèšèªïŒJavaãªã©ïŒã®äž¡æ¹ããåºå¥ããRustã®äž»èŠãªæ©èœã®æåã®æ©èœã§ãã å®éãäžæ¹ã§ãRustã¯éçºè ã«ããŒã¿ã®é çœ®å Žæãå¶åŸ¡ããæ©èœãæäŸãããã€ã³ã¿ãŒã®ã¿ã€ãã«ããåé¢ãå°å ¥ããã³ã³ãã€ã«æ®µéã§ã®äœ¿çšãå¶åŸ¡ããŸãã äžæ¹ãèšèªã®æçµããŒãžã§ã³ã§ã¯æ¬æ ŒçãªGCã«çœ®ãæãããããªã³ã¯ã«ãŠã³ãã¡ã«ããºã ã«ãããèªåãªãœãŒã¹ç®¡çãæäŸãããŸãã
Rustã«ã¯ãããŸããŸãªã¿ã€ãã®ã¡ã¢ãªã«ãããªããžã§ã¯ããã¢ãã¬ã¹æå®ããããŸããŸãªã«ãŒã«ã«åŸããã€ã³ã¿ãŒãããã€ããããŸãã
- å ±æãã€ã³ã¿ãŒïŒç®¡çããã¯ã¹ïŒã ã¿ã¹ã¯ã®ããŒã«ã«ããŒãã«ããããŒã¿ãæããŸãã è€æ°ã®å ±æãã€ã³ã¿ãŒãåããªããžã§ã¯ããã¢ãã¬ã¹æå®ã§ããŸãã
- äžæã®ãã€ã³ã¿ãŒïŒææããã¯ã¹ïŒã ãã¹ãŠã®ã¿ã¹ã¯ã«å ±éã®ã亀æããŒãã«ããããŒã¿ãæããŸãã äžåºŠã«1ã€ã®ãªããžã§ã¯ãããã¢ãã¬ã¹æå®ã§ããŸããïŒãARCã¢ãžã¥ãŒã«ãã»ã¯ã·ã§ã³ã®ã«ãŒã«ã®äŸå€ãåç §ïŒã
- äžæãã€ã³ã¿ãŒïŒåçšãã€ã³ã¿ãŒïŒã ã¹ã¿ãã¯ãããŒã«ã«ããŒããŸãã¯äº€æããŒããªã©ãããããã¿ã€ãã®ãªããžã§ã¯ããæãããšãã§ãããŠãããŒãµã«ãã€ã³ã¿ãŒã ãããã¯äž»ã«ããªããžã§ã¯ãã®é 眮ã®ã¿ã€ããéèŠã§ãªãå Žåã«é¢æ°å ã®ããŒã¿ãåŠçãããŠãããŒãµã«ã³ãŒããèšè¿°ããããã«äœ¿çšãããŸãã
- å°ã暪ã«ããã®ã¯ãã¹ã¿ãã¯ã«çœ®ããããªããžã§ã¯ãã§ãã ãããã®ã¢ãã¬ã¹æå®ã«ã¯ãåºå¥ã§ããã¿ã€ãã®ãã€ã³ã¿ãŒã¯ãããŸããã
æŠç¥çã«ãRustã¡ã¢ãªã¢ãã«ã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãã

ã¹ã¿ãã¯äœ¿çšé
let x = Point {x: 1f, y: 1f}; // (1) let y = x; // (2)
ãããã£ãŠãã³ãŒãïŒ1ïŒã¯ãPointåã®ãªããžã§ã¯ããããããåŒã³åºãããã¿ã¹ã¯ã®ã¹ã¿ãã¯ã«é 眮ããŸãã ãã®ãããªãªããžã§ã¯ãïŒ2ïŒãã³ããŒãããšããªããžã§ã¯ãxãžã®ãã€ã³ã¿ãŒã§ã¯ãªããPointã¿ã€ãã®æ§é å šäœãã³ããŒãããŸãã
æ å ±ïŒå€æ°
äžèšã®äŸãããããããã«ãå€æ°ãäœæããããã«Rustã§letããŒã¯ãŒãã䜿çšãããŸãã ããã©ã«ãã§ã¯ããã¹ãŠã®å€æ°ã¯å®æ°ã§ãããmutããŒã¯ãŒããè¿œå ããŠå¯å€å€æ°ãäœæããå¿ èŠããããŸãã ãããã£ãŠãPointåã®å¯å€å€æ°ãäœæãããšã次ã®ããã«ãªããŸããlet mut x = Point {xïŒ1fãyïŒ1f};ã
å€æ°ãæäœãããšããå®æ°ã§ããããšãå€æããã®ã¯ããŒã¿ã§ãããã³ã³ãã€ã©ããããªãã¯ãã«ãã£ãŠããããå€æŽããããšããè©Šã¿ã泚ææ·±ãç£èŠããããšãèŠããŠããããšã¯éåžžã«éèŠã§ãã
let x = Point {x:1, y:2}; let y = Point {x:2, y:3}; let mut px = &x; // (1) let py = &y; px.x = 42; // (2) px = py; // (3)
ãã®ãããïŒ1ïŒå®æ°ããŒã¿ãæãå¯å€å€æ°ãäœæããããšã¯ããªãå¯èœã§ãããïŒ2ïŒããŒã¿èªäœãå€æŽããããšãããšãã³ã³ãã€ã«æ®µéã§ãšã©ãŒãçºçããŸãã ãã ããå®æ°Pointãªããžã§ã¯ãã®ã¢ãã¬ã¹ãæ ŒçŽãã以åã«äœæãããå€æ°ã®å€ãå€æŽããããšã¯æå¹ã§ãïŒ3ïŒã
error: assigning to immutable field px.x = 42; ^~~~~
å ±æãã€ã³ã¿ãŒ
å ±æãã€ã³ã¿ãŒã¯ãããŒã«ã«ã¿ã¹ã¯ããŒãã«ãããªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãšããŠäœ¿çšãããŸãã åã¿ã¹ã¯ã«ã¯ç¬èªã®ããŒã«ã«ããŒãããããã¿ã¹ã¯å ã«ãããªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãå¢çå€ã«æž¡ãããšã¯ã§ããŸããã å ±æãã€ã³ã¿ãŒãäœæããã«ã¯ãåé æŒç®å@ã䜿çšããŸã
let x = @Point {x: 1f, y: 1f};
ã¹ã¿ãã¯ãªããžã§ã¯ããšã¯ç°ãªããã³ããŒæã«ã¯ãããŒã¿ã§ã¯ãªããã€ã³ã¿ãŒã®ã¿ãã³ããŒãããŸãã ãã®ããããã£ããããã®ã¿ã€ãã®ãã€ã³ã¿ãŒã®ååã¯ãC ++èšèªã®shared_ptrã«éåžžã«äŒŒãŠããããããã®ã¿ã€ãã®ãã€ã³ã¿ãŒã®ååã«ãªã£ãŠããŸãã
let y = x; // x y // Point
ãŸããç¬èªã®åãžã®ãã€ã³ã¿ãå«ãæ§é ãäœæããããšã¯äžå¯èœã§ãããšããäºå®ã«æ³šæããå¿ èŠããããŸãïŒå žåçãªäŸã¯ãåçŽã«æ¥ç¶ããããªã¹ãã§ãïŒã ã³ã³ãã€ã©ããã®ãããªæ§é ãèš±å¯ããã«ã¯ãOptionïŒ1ïŒåã§ãã€ã³ã¿ãã©ããããå¿ èŠããããŸãã
struct LinkedList<T> { data: T, nextNode: Option<@LinkedList<T>> // (1) }
äžæã®ãã€ã³ã¿ãŒ
å ±æãã€ã³ã¿ãŒã®ãããªäžæã®ãã€ã³ã¿ãŒã¯ãããŒãäžã®ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã§ããããã®é¡äŒŒç¹ã¯ããã«ãããŸãã äžæã®ãã€ã³ã¿ãŒã«ãã£ãŠã¢ãã¬ã¹æå®ãããããŒã¿ã¯ããã¹ãŠã®ã¿ã¹ã¯ã«å ±éã®äº€æããŒãã«ãããŸãã äžæã®ãã€ã³ã¿ãŒãäœæããã«ã¯ãåé æŒç®åãã䜿çšããŸã
let p = ~Point {x: 1f, y: 1f};
äžæã®ãã€ã³ã¿ã¯æææš©ã®ã»ãã³ãã£ã¯ã¹ãå®è£ ããããããªããžã§ã¯ãã¯1ã€ã®äžæã®ãã€ã³ã¿ã®ã¿ãã¢ãã¬ã¹æå®ã§ããŸãã C ++éçºè ã¯ãäžæã®Rustãã€ã³ã¿ãŒãšSTLã®unique_ptrã¯ã©ã¹ã®é¡äŒŒç¹ãèŠã€ããå¯èœæ§ããããŸãã
let new_p = p; // (1) let val_x = px; // (2)
ãã€ã³ã¿ãŒpã®ãã€ã³ã¿ãŒnew_pã«ïŒ1ïŒãå²ãåœãŠããšãnew_pã¯ä»¥åã«äœæãããPointåã®ãªããžã§ã¯ããæãå§ãããã€ã³ã¿ãŒpã¯åæåãããŸããã åæå解é€ãããå€æ°ïŒ2ïŒãæäœããããšããå Žåãã³ã³ãã€ã©ãŒã¯ç§»åå€ãšã©ãŒã®äœ¿çšãçæãããã®åŸã®å ã®åæå解é€ã§ãã€ã³ã¿ãŒãå²ãåœãŠã代ããã«å€æ°ã®ã³ããŒãäœæããããšãææ¡ããŸãã
let p = ~Point {x: 1f, y: 1f}; let new_p = p.clone(); // (1)
copyïŒ1ïŒã®æ瀺çãªäœæã®ãããã§ãnew_pã¯ä»¥åã«äœæãããPointåã®ãªããžã§ã¯ãã®ã³ããŒãæãããã€ã³ã¿ãŒpã¯å€ãããŸããã cloneã¡ãœãããPointæ§é ã«é©çšããã«ã¯ãïŒ[derivingïŒCloneïŒ]å±æ§ã䜿çšããŠæ§é ã宣èšããå¿ èŠããããŸãã
#[deriving(Clone)] struct Point {x: float, y: float}
äžæçãªãã€ã³ã¿ãŒ
äžæçãªãã€ã³ã¿ãŒ-å¯èœãªã¡ã¢ãªã®çš®é¡ïŒã¹ã¿ãã¯ãããŒã«ã«ãŸãã¯ããŒã亀æãããã³ããŒã¿æ§é ã®å éšã¡ã³ããŒïŒã«ãããªããžã§ã¯ããæããã€ã³ã¿ãŒã ç©çã¬ãã«ã§ã¯ãäžæãã€ã³ã¿ãŒã¯å žåçãªCãã€ã³ã¿ãŒã§ããããã®çµæãã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãã£ãŠç£èŠããããè¿œå ã®ãªãŒããŒããããçºçããŸããã åæã«ãCãã€ã³ã¿ãŒãšã®äž»ãªéãã¯ãå®å šãªäœ¿çšã®å¯èœæ§ãä¿èšŒããããã«ã³ã³ãã€ã«æ®µéã§å®è¡ãããè¿œå ã®ãã§ãã¯ã§ãã äžæçãªãã€ã³ã¿ãŒãäœæããã«ã¯ãåé æŒç®åïŒã䜿çšããŸã
let on_the_stack = &Point {x: 3.0, y: 4.0}; // (1)
ã¿ã€ãPointã®ãªããžã§ã¯ããã¹ã¿ãã¯äžã«äœæããïŒ1ïŒãäžæãã€ã³ã¿ãŒãon_the_stackã«æ ŒçŽãããŸããã ãã®ã³ãŒãã¯æ¬¡ã®ãããªãã®ã§ãã
let on_the_stack = Point {x: 3.0, y: 4.0}; let on_the_stack_pointer = &on_the_stack;
ã¹ã¿ãã¯å以å€ã®åã¯ãã¢ãã¬ã¹ãåãæŒç®åã䜿çšããããšãªããäžæçãªãã€ã³ã¿ãŒã«èªåçã«å€æãããŸããããã«ããããã€ã³ã¿ãŒã®åãéèŠã§ãªãå Žåã«é¢æ°ïŒ1ïŒãç°¡åã«èšè¿°ã§ããŸãã
let on_the_stack : Point = Point {x: 3.0, y: 4.0}; let managed_box : @Point = @Point {x: 5.0, y: 1.0}; let owned_box : ~Point = ~Point {x: 7.0, y: 9.0}; fn compute_distance(p1: &Point, p2: &Point) -> float { // (1) let x_d = p1.x - p2.x; let y_d = p1.y - p2.y; sqrt(x_d * x_d + y_d * y_d) } compute_distance(&on_the_stack, managed_box); compute_distance(managed_box, owned_box);
次ã«ãããŒã¿æ§é ã®å éšèŠçŽ ãžã®äžæçãªãã€ã³ã¿ãŒãååŸããæ¹æ³ã®ç°¡åãªå³ã瀺ããŸãã
let y = &point.y;
ã¿ã€ã ãã€ã³ã¿ã®å¯¿åœãç£èŠããããšã¯ãããªãããªã¥ãŒã ãããã確ç«ããããããã¯ã§ã¯ãããŸããã å¿ èŠã«å¿ããŠãèšäºãRust Borrowed Pointers Tutorial and Lifetime Notationãã§è©³çŽ°ãèªãããšãã§ããŸãã
ãã€ã³ã¿ãŒã®éåç §
ãã€ã³ã¿ãŒã䜿çšããŠã¢ãã¬ã¹æå®ãããå€ã«ã¢ã¯ã»ã¹ããã«ã¯ããã€ã³ã¿ãŒã®åç §è§£é€æäœãå®è¡ããå¿ èŠããããŸãã æ§é åãªããžã§ã¯ãã®ãã£ãŒã«ãã«ã¢ã¯ã»ã¹ãããšãåç §è§£é€ãèªåçã«å®è¡ãããŸãã
let managed = @10; let owned = ~20; let borrowed = &30; let sum = *managed + *owned + *borrowed;
ãã€ã³ã¿ãŒéã®å€æ
Rustã§ã®äœæ¥ãéå§ããçŽåŸã«ããäžæã®ãã€ã³ã¿ãŒã䜿çšããŠã¢ãã¬ã¹æå®ããããªããžã§ã¯ããå ±æãªããžã§ã¯ãã«ããŸãã¯ãã®éã«å€æããæ¹æ³ã¯ïŒããšããçåãçããŸãããã®è³ªåã«å¯Ÿããçãã¯çããæåã¯ããèœèããŸãã ããã«ã€ããŠããèããŠã¿ããšããªããžã§ã¯ãã¯ç°ãªãããŒãã«ãããç°ãªãã«ãŒã«ã«åŸãããããã®ãããªå€æã®æ段ã¯ååšãããæ段ãããåŸãªãããšãæããã«ãªããŸãããªããžã§ã¯ãã¯äŸåé¢ä¿ã°ã©ããæã€ããšãã§ãããããèªåçã«è¿œè·¡ããã®ãå°é£ã§ãã ãã®ããããã€ã³ã¿éã§å€æããå¿ èŠãããå ŽåïŒããŒãéã§ãªããžã§ã¯ãã移åããã ãã®å ŽåïŒãã·ãªã¢ã«åã䜿çšã§ãããªããžã§ã¯ãã®ã³ããŒãäœæããå¿ èŠããããŸãã
ã¿ã¹ã¯
Rustã®2çªç®ã®éèŠãªæ©èœã¯ã䞊åã¢ããªã±ãŒã·ã§ã³ã®äœæã§ãã åæå®è¡ã¢ããªã±ãŒã·ã§ã³ãäœæãããšããç¹ã§ã¯ãRustã¯ã¢ã¯ã¿ãŒã¢ãã«ãšãErlangãšLimboãšã®éã®ã¡ãã»ãŒãžã³ã°ã§ã®ãã£ãã«ãåããErlangã«äŒŒãŠããŸãã ãã®å Žåãéçºè ã«ã¯ãã¡ãã»ãŒãžãéä¿¡ãããšãã«ã¡ã¢ãªãã³ããŒããããåã«ãªããžã§ã¯ãã®æææš©ãè²æž¡ããããéžæããæ©äŒãäžããããŸãã ãŸããè€æ°ã®ã¿ã¹ã¯ãåããªããžã§ã¯ããšé£æºããŠæ©èœããå Žåã1人ã®ã©ã€ã¿ãŒãè€æ°ã®ãªãŒããŒã®ã¢ã¯ã»ã¹ãç°¡åã«æŽçã§ããŸãã äœæãããã¿ã¹ã¯ã«ã€ããŠã¯ãæé©ãªã¹ã±ãžã¥ãŒã©ãéžæããããç¬èªã®ã¹ã±ãžã¥ãŒã©ãäœæããæ©äŒããããŸãã
詳现ã«ã€ããŠã¯ãdo-syntax
ã¿ã¹ã¯ã®æäœã®èª¬æã«é²ãåã«ãRustãé«éé¢æ°ã®æäœãç°¡ç¥åããããã«äœ¿çšããdo-syntaxãç解ããããšããå§ãããŸãã äŸãšããŠãåé¢æ°ã䜿çšããŠãé åã®åèŠçŽ ãžã®ãã€ã³ã¿ãŒïŒ1ïŒãopé¢æ°ã«æž¡ãããšãã§ããŸãã
fn each(v: &[int], op: &fn(v: &int)) { let mut n = 0; while n < v.len() { op(&v[n]); // (1) n += 1; } }
do-syntaxïŒ1ïŒã䜿çšããŠåé¢æ°ã䜿çšãããšãé åã®åèŠçŽ ã衚瀺ã§ããŸããå€ãã©ã ãã«æž¡ãããã®ã§ã¯ãªããããŒã¿ã«ã¢ã¯ã»ã¹ããããã«éåç §ããå¿ èŠããããã€ã³ã¿ãŒïŒ2ïŒãå¿ããªãã§ãã ããïŒ
do each([1, 2, 3]) |n| { // (1) io::println(n.to_str()); // (2) }
doæ§æã¯æ§æç³ã§ããããã以äžã®è¡šèšã¯doæ§æã䜿çšããè¡šèšãšåçã§ãã
each([1, 2, 3], |n| { io::println(n.to_str()); });
ã¿ã¹ã¯ãå®è¡ãã
Rustã§ã®ã¿ã¹ã¯ã®äœæãšå®è¡ã¯éåžžã«ç°¡åã§ãã ã¿ã¹ã¯ã®æäœã«é¢é£ããã³ãŒãã¯std :: taskã¢ãžã¥ãŒã«ã«éäžããŠãããã¿ã¹ã¯ãäœæããŠéå§ããæãç°¡åãªæ¹æ³ã¯ããã®ã¢ãžã¥ãŒã«ããspawné¢æ°ãåŒã³åºãããšã§ãã
use std::task; fn print_message() { println("Message form task 1"); } fn main() { spawn(print_message); // (1) spawn( || println("Message form task 2") ); // (2) do spawn { // (3) println("Message form task 3"); } }
spawné¢æ°ã¯ãã¯ããŒãžã£ãŒãåŒæ°ãšããŠåãåãããããã¿ã¹ã¯ãšããŠèµ·åããŸãïŒRustã®ã¿ã¹ã¯ã¯ç·ã®ã¹ã¬ããã®äžã«å®è£ ãããããšãå¿ããªãã§ãã ããïŒã ã³ãŒããå®è¡ãããçŸåšã®ã¿ã¹ã¯ãååŸããã«ã¯ãã¿ã¹ã¯ã¢ãžã¥ãŒã«ããget_taskïŒïŒã¡ãœããã䜿çšã§ããŸãã ã¯ããŒãžã£ã¯ã¿ã¹ã¯ã®ãã¬ãŒã ã¯ãŒã¯å ã§å®è¡ããããããå®è¡ããã¿ã¹ã¯ãéå§ãã3ã€ã®æ¹æ³ãæ³å®ããããšã¯é£ãããããŸãããæ§æïŒ3ïŒã
ã¿ã¹ã¯éã®çžäºäœçš
Rustã¡ã¢ãªã¢ãã«ã¯ãäžè¬çãªå Žåãç°ãªãã¿ã¹ã¯ïŒå ±æã¡ã¢ãªã¢ãã«ïŒããåãã¡ã¢ãªãžã®å ±åã¢ã¯ã»ã¹ãèš±å¯ããã代ããã«ã¿ã¹ã¯éã®ã¡ãã»ãŒãžäº€æïŒã¡ãŒã«ããã¯ã¹ã¢ãã«ïŒãæäŸããŸãã åæã«ãããã€ãã®ã¿ã¹ã¯ã§ã¯ãèªã¿åãå°çšã¢ãŒããšãã«ããªãŒããŒã¢ãŒãã§å ±æã¡ã¢ãªãæäœã§ããŸãã ã¿ã¹ã¯éã®çžäºäœçšãæŽçããããã«ãRustã¯ä»¥äžã®ã¡ãœãããæäŸããŸã
- std :: commã¢ãžã¥ãŒã«ã®äœã¬ãã«ãã£ãã«ãšããŒãã
- ãã£ãã«ããã³ããŒããä»ããé«ã¬ãã«ã®æœè±¡åextra :: comm;
- äœåãª::ãã©ãããã€ããããã€ããªããŒã¿ãéä¿¡ããããã®ãã£ãã«ã
äœã¬ãã«ã®ã¡ãã»ãŒãžã³ã°
çŸæç¹ã§ã¿ã¹ã¯éã§æãåºã䜿çšãããŠããæ¹æ³ã¯ãstd :: commã¢ãžã¥ãŒã«ã§ãã std :: commã®ã³ãŒãã¯ãååã«ãããã°ãããååã«ææžåãããŠãããããªã䜿ããããã§ãã std :: commã¡ãã»ãŒãžã³ã°ãšã³ãžã³ã®åºç€ã¯ã¹ã¬ããã§ãããããã¯ãã£ãã«ãšããŒããä»ããŠæäœãããŸãã ã¹ããªãŒã ã¯ãããŒãã䜿çšããŠã¡ãã»ãŒãžãéä¿¡ãããã£ãã«ã䜿çšããŠéä¿¡æ å ±ãåä¿¡ããåæ¹åéä¿¡ã¡ã«ããºã ã§ãã ã¹ããªãŒã ã䜿çšããæãç°¡åãªäŸã¯æ¬¡ã®ãšããã§ãã
let (chan, port) = stream(); // (1) port.send("data"); // (2) // port.send(1); // (3) println(chan.recv()); // (4)
ãã®äŸã§ã¯ããã£ãã«ãšããŒãã§æ§æããããã¢ïŒ1ïŒãäœæããããããã¯æååããŒã¿åã®éä¿¡ïŒ2ïŒã«äœ¿çšãããŸãã streamïŒïŒé¢æ°ã®ãããã¿ã€ãã«ã¯ç¹ã«æ³šæãæãå¿ èŠããããŸãããããã¿ã€ãã¯fn stream <TïŒSend>ïŒïŒ->ïŒPortãChanïŒã®ããã«ãªããŸãã ãããã¿ã€ããããããããã«ããã£ãã«ãšããŒãã¯ãã³ãã¬ãŒãã¿ã€ãã§ãããäžèŠãäžèšã®ã³ãŒãããã¯æããã§ã¯ãããŸããã ãã®å Žåã転éãããããŒã¿ã®ã¿ã€ãã¯æåã®äœ¿çšã«åºã¥ããŠèªåçã«è¡šç€ºãããŸãã ãã®ããããŠãããïŒ3ïŒãã¹ããªãŒã ã«éä¿¡ããè¡ã®ã³ã¡ã³ãã解é€ãããšãã³ã³ãã€ã©ãŒã¯ãšã©ãŒã¡ãã»ãŒãžã衚瀺ããŸãã
error: mismatched types: expected `&'static str` but found `<VI0>` (expected &'static str but found integral variable
Sendãã©ã¡ãŒã¿ãŒã¯ã©ã¹ã«ã¯ç¹ã«æ³šæãæãããŸããã€ãŸããçŸåšã®ã¿ã¹ã¯ã®å€éšãžã®è»¢éããµããŒããããªããžã§ã¯ãã®ã¿ãã¹ããªãŒã ã䜿çšããŠè»¢éã§ããŸãã
ã¹ããªãŒã ããããŒã¿ãååŸããã«ã¯ãrecvïŒïŒé¢æ°ã䜿çšããŸãããã®é¢æ°ã¯ãããŒã¿ãè¿ããã衚瀺ããããŸã§ã¿ã¹ã¯ããããã¯ããŸãã äžèšã®äŸãèŠããšã1ã€ã®ã¿ã¹ã¯ã®ãã¬ãŒã ã¯ãŒã¯å ã§ã¹ã¬ããã䜿çšããŠã¡ãã»ãŒãžãéä¿¡ããããšã«ã¯å®çšçãªæå³ããªãããããŸã£ãã圹ã«ç«ããªããšããç念ãå¿ã³å¯ã£ãŠããŸãã ãããã£ãŠãã¹ã¬ããã䜿çšããŠã¿ã¹ã¯éã§æ å ±ã転éãããªã©ãããå®çšçãªãã®ã«é²ã䟡å€ããããŸãã
let value = vec::from_fn(5, |x| x + 1); // (1) let (server_chan, server_port) = stream(); // (2) let (client_chan, client_port) = stream(); // (3) do task::spawn { let val: ~[uint] = server_chan.recv(); // (4) let res = val.map(|v| {v+1}); client_port.send(res) // (5) } server_port.send(value); // (6) io::println(fmt!("Result: %?", client_chan.recv())); // (7)
ã¹ããªãŒã ãæäœããéã«æåã«æ³šæããå¿ èŠãããã®ã¯ãäžæã®ãã€ã³ã¿ãŒã§ã¢ãã¬ã¹æå®ãããå€ãæž¡ãå¿ èŠãããããšã§ããfrom_fnïŒïŒïŒ1ïŒé¢æ°ã¯ãã®ãããªé åãäœæããã ãã§ãã ã¹ããªãŒã ã¯åæ¹åã§ãããããèŠæ±ã®éä¿¡ïŒ2ïŒãšå¿çã®åä¿¡ïŒ3ïŒã«ã¯2ã€ã®ã¹ããªãŒã ãå¿ èŠã§ãã recvïŒïŒé¢æ°ã䜿çšããŠãããŒã¿ã¯ã¹ããªãŒã ïŒ4ïŒããèªã¿åããã䜿çšå¯èœãªããŒã¿ããªãå Žåãã¹ããªãŒã ã¯ã¿ã¹ã¯ã衚瀺ããããŸã§ãããã¯ããŸãã çµæãã¯ã©ã€ã¢ã³ãã«éä¿¡ããã«ã¯ããµãŒããŒã§ã¯ãªãã¯ã©ã€ã¢ã³ãã¹ããªãŒã ã«å±ããsendïŒïŒïŒ5ïŒé¢æ°ã䜿çšããŸãã åæ§ã«ããµãŒããŒã¿ã¹ã¯ã«éä¿¡ããããã®ããŒã¿ãåŠçããå¿ èŠããããŸãããããã¯ããµãŒããŒããŒãã«é¢é£ããsendïŒïŒé¢æ°ã䜿çšããŠæžã蟌ãŸããŸãïŒ6ïŒã æåŸã«ããµãŒããŒã¿ã¹ã¯ã«ãã£ãŠéä¿¡ãããçµæãã¯ã©ã€ã¢ã³ãã¹ããªãŒã ããèªã¿åãããŸãïŒ7ïŒã
ãããã£ãŠããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ãããµãŒããŒåŽã§ã¡ãã»ãŒãžãåä¿¡ããã«ã¯ãserver_chanãserver_portã¹ããªãŒã ã䜿çšãããŸãã ã¹ããªãŒã ã®åæ¹åæ§ã®ãããã¯ã©ã€ã¢ã³ãã¹ããªãŒã ã¯ãclient_chanãšclient_portã®ãã¢ã§æ§æããããµãŒããŒèšç®ã®çµæãååŸããããã«äœæãããŸããã
ã¹ããªãŒã å ±æ
ã¹ããªãŒã ã¯åæ¹åã®ããŒã¿è»¢éã¡ã«ããºã ã§ããããone-receiver-many-sendersãã¢ãŒãã§ã®åäœãä¿èšŒããã¡ã«ããºã ããããããããŒã¿ãéä¿¡ãããŠãŒã¶ãŒããšã«æ°ããã¹ããªãŒã ãäœæããå¿ èŠã¯ãããŸããã
enum command { // (1) print_hello(int), stop } ... let (server_chan, server_port) = stream(); // (2) let (client_chan, client_port) = stream(); // (3) do spawn { // (4) let mut hello_count = 0; let mut done = false; while !done { let req: command = server_chan.recv(); // (5) match req { print_hello(client_id) => { println( fmt!("Hello from client #%d", client_id)); hello_count += 1; } stop => { println("Stop command received"); done = true; } } } client_port.send(hello_count); // (6) } let server_port = SharedChan::new(server_port); // (7) for i in range(0, 5) { let server_port = server_port.clone(); // (8) do spawn { server_port.send(print_hello(i)); // (9) } } server_port.send(stop); println(fmt!("Result: %?", client_chan.recv()));
ãã®ãããããã³ã1ãªãŒããŒ1ã©ã€ã¿ãŒãã¹ããŒã ã®å ŽåããµãŒããŒïŒ2ïŒããã³ã¯ã©ã€ã¢ã³ãïŒ3ïŒã®ã¹ã¬ãããäœæãããµãŒããŒã¿ã¹ã¯ïŒ3ïŒãå®è¡ããå¿ èŠããããŸãã ãµãŒããŒã¿ã¹ã¯ã®ããžãã¯ã¯éåžžã«åçŽã§ãïŒã¯ã©ã€ã¢ã³ãã«ãã£ãŠéä¿¡ããããµãŒããŒãã£ãã«ããããŒã¿ãèªã¿åãïŒ9ïŒãç»é¢ã«èŠæ±ã®åä¿¡ã«é¢ããã¡ãã»ãŒãžã衚瀺ããåä¿¡ããprint_helloïŒ5ïŒèŠæ±ã®çµæã®æ°ãã¯ã©ã€ã¢ã³ãã¹ããªãŒã ã«éä¿¡ããŸãã ã©ã€ã¿ãŒãè€æ°ãããããïŒ7ïŒChanã®ä»£ããã«SharedChanã«å€æããŠãµãŒããŒããŒãã®ã¿ã€ããå€æŽããcloneïŒïŒã¡ãœããã䜿çšããŠåã©ã€ã¿ãŒã®ããŒãïŒ8ïŒã®äžæã®ã³ããŒãäœæããå¿ èŠããããŸãã ããŒãã§ã®ãããªãäœæ¥ã¯ãåã®äŸãšå€ãããŸããïŒsendïŒïŒã¡ãœããã䜿çšããŠããŒã¿ããµãŒããŒïŒ9ïŒã«éä¿¡ããŸãããããŒã¿ãè€æ°ã®ã¿ã¹ã¯ããåæã«éä¿¡ãããç¹ãç°ãªããŸãã
ãã®äŸã§ã¯ãã¹ããªãŒã ã®æäœæ¹æ³ã®èª¬æã«å ããŠã1ã€ã®ã¹ããªãŒã ã䜿çšããŠããã€ãã®ç°ãªãã¿ã€ãã®ã¡ãã»ãŒãžãéä¿¡ããæ¹æ³ã瀺ããŸãã ã¹ããªãŒã ã«ãã£ãŠéä¿¡ãããããŒã¿ã®ã¿ã€ãã¯ã³ã³ãã€ã«æ®µéã§èšå®ããããããããŸããŸãªã¿ã€ãã®ããŒã¿ã転éããã«ã¯ãã·ãªã¢ã«åãšããã«ç¶ããã€ããªããŒã¿ã®è»¢éïŒãã®æ¹æ³ã«ã€ããŠã¯ããªããžã§ã¯ãã®éä¿¡ãã»ã¯ã·ã§ã³ã§èª¬æïŒãŸãã¯åæã®è»¢éïŒ1ïŒã䜿çšããå¿ èŠããããŸãã Rustã®åæã¯ããã®æ§è³ªäžãCèšèªãŸãã¯Variantåã®é¢é£ä»ãã«äŒŒãŠãããã»ãšãã©ãã¹ãŠã®é«ã¬ãã«ããã°ã©ãã³ã°èšèªã§äœããã®åœ¢ã§ååšããŸãã
åºè·ãªããžã§ã¯ã
äžæã®ãã€ã³ã¿ãŒã§ã¢ãã¬ã¹æå®ãããå€ã転éããå¿ èŠãåé¡ã«ãªãå Žåãflatpipesã¢ãžã¥ãŒã«ã圹ç«ã¡ãŸãã ãã®ã¢ãžã¥ãŒã«ã䜿çšãããšãã·ãªã¢ã«åããµããŒãããé åãŸãã¯ãªããžã§ã¯ãã®åœ¢åŒã§ãã€ããªããŒã¿ãéåä¿¡ã§ããŸãã
#[deriving(Decodable)] // (1) #[deriving(Encodable)] // (2) struct EncTest { val1: uint, val2: @str, val3: ~str } ... let (server_chan, server_port) = flatpipes::serial::pipe_stream(); // (3) do task::spawn { let value = @EncTest{val1: 1u, val2: @"test string 1", val3: ~"test string 2"}; server_port.send(value); // (4) } let val = server_chan.recv(); server_port.send(value); // (5)
äŸãããããããã«ããã©ãããã€ãã®æäœã¯éåžžã«ç°¡åã§ãã ãªããžã§ã¯ãããã©ãããã€ããä»ããŠéä¿¡ãããæ§é ã¯ãserializableïŒ1ïŒããã³deserializableïŒ2ïŒãšããŠå®£èšããå¿ èŠããããŸãã ãã©ãããã€ãã®äœæïŒ3ïŒã¯ããã£ãã«ãšããŒãã䜿çšããŠã¡ãã»ãŒãžãåä¿¡ïŒ4ïŒããã³éä¿¡ïŒ5ïŒããã®ãšåãããã«ãæè¡çã«ã¯éåžžã®ã¹ããªãŒã ã®äœæãšéãã¯ãããŸããã ãã©ãããã€ããšã¹ããªãŒã ã®äž»ãªéãã¯ãéä¿¡åŽã§ãªããžã§ã¯ãã®ãã£ãŒãã³ããŒãäœæããããšãšãåä¿¡åŽã§æ°ãããªããžã§ã¯ããäœæããããšã§ãã ãã®ã¢ãããŒãã®ãããã§ãéåžžã®ã¹ããªãŒã ãšæ¯èŒããŠãã©ãããã€ãã§äœæ¥ãããªãŒããŒããããå¢å ããŸãããã¿ã¹ã¯éã§ããŒã¿ã転éããèœåã¯å¢å ããŸãã
é«ã¬ãã«ã®ã¡ãã»ãŒãžã³ã°æœè±¡å
äžèšã®ã»ãšãã©ã®äŸã§ã¯ã2ã€ã®ã¹ããªãŒã ãäœæãããŸãã1ã€ã¯ãµãŒããŒã«ããŒã¿ãéä¿¡ããããã®ãã®ã§ããã1ã€ã¯ãµãŒããŒããããŒã¿ãåä¿¡ããããã®ãã®ã§ãã ãã®ã¢ãããŒãã¯å ·äœçãªã¡ãªãããããããããã³ãŒããç¡é§ã«ããã ãã§ãã ãã®ç¹ã§ãã¢ãžã¥ãŒã«extraïŒcommãäœæãããŸãããããã¯ãstd :: commã«å¯Ÿããé«ã¬ãã«ã®æœè±¡åã§ãããåäžã¹ããªãŒã å ã§ã®åæ¹åéä¿¡ãå¯èœã«ããDuplexStreamãå«ãŸããŠããŸãã ãã¡ãããDuplexStreamã®ãœãŒã¹ã³ãŒããèŠããšãããã¯æšæºã¹ããªãŒã ã®ãã¢ã«å¯Ÿãã䟿å©ãªã¢ããªã³ã«éããªãããšãæããã«ãªããŸãã
let value = ~[1, 2, 3, 4, 5]; let (server, client) = DuplexStream(); // (1) do task::spawn { let val: ~[uint] = server.recv(); // (2) io::println(fmt!("Value: %?", val)); let res = val.map(|v| {v+1}); server.send(res) // (3) } client.send(value); // (4) io::println(fmt!("Result: %?", client.recv())); // (5)
DuplexStreamã䜿çšããå ŽåãïŒ1ïŒ2ã€ã®åæ¹åã¹ããªãŒã ã®åäžã®ãã¢ãäœæãããã©ã¡ããã¡ãã»ãŒãžã®éä¿¡ãšåä¿¡ã®äž¡æ¹ã«äœ¿çšã§ããŸãã ãµãŒããŒãªããžã§ã¯ãã¯ãã¿ã¹ã¯ã®ã³ã³ããã¹ãã«ãã£ãŠãã£ããã£ããããµãŒããŒã¿ã¹ã¯ã§ã®ã¡ãã»ãŒãžã®åä¿¡ïŒ2ïŒãšéä¿¡ïŒ3ïŒãããã³ã¯ã©ã€ã¢ã³ãã¿ã¹ã¯ã§ã®ã¯ã©ã€ã¢ã³ããªããžã§ã¯ãïŒ4,5ïŒã«äœ¿çšãããŸãã DuplexStreamã䜿çšããåçã¯ãéåžžã®ã¹ããªãŒã ã䜿çšããå Žåãšå€ãããŸããããè£å©ãªããžã§ã¯ãã®æ°ãæžããããšãã§ããŸãã
ã¢ãŒã¯ã¢ãžã¥ãŒã«
ã¡ãã»ãŒãžãéä¿¡ãããã¹ãŠã®é åã«ãããããããé ããæ©ããããè€æ°ã®ã¿ã¹ã¯ããåæã«ã¢ã¯ã»ã¹ããå¿ èŠã®ãã倧ããªããŒã¿æ§é ã§äœããã¹ããïŒããšããçåãçããŸããã¢ããªã±ãŒã·ã§ã³ãããã³ãã®ã¡ã³ããã³ã¹ã¯æ¬åœã®æªå€¢ã«å€ãããŸãã ãã®ãããªå Žåã®ããã«ãArcã¢ãžã¥ãŒã«ãäœæãããŸãããããã«ãããè€æ°ã®ã¿ã¹ã¯ããåããªããžã§ã¯ããžã®å ±åã¢ã¯ã»ã¹ãæŽçã§ããŸãã
äžæã®èªã¿åãå°çšãã€ã³ã¿ãŒãå ±æãã
æåã«ãæãåçŽãªã±ãŒã¹-è€æ°ã®ã¿ã¹ã¯ããã®äžå€ããŒã¿ãžã®ã¢ã¯ã»ã¹ã®å ±æ-ã«å¯ŸåŠããå¿ èŠããããŸãã Arc, (Atomically Reference-Counter) . ARC- pub fn new(data: T) -> Arc T .
impl<T:Freeze+Send> Arc<T> { pub fn new(data: T) -> Arc<T> { ... } ... }
Send, , Freeze, T ( Rust deeply immutable objects).
let data = arc::Arc::new(~[1, 2, 3, 4, 5]); // (1) let shared_data = data.clone(); // (2) do spawn { let val = shared_data.get(); // (3) println(fmt!("Shared array: %?", val)); } println(fmt!("Original array: %?", data.get())); // (4)
, Arc, â . , , Arc (1), Arc (2), (3), (4) .
R/W
RWArc . , RWArc â â, , , , . , , RO , , RW , , Rust . : , .
let data = arc::RWArc::new(~[1, 2, 3, 4, 5]); // (1) do 5.times { let reader = data.clone(); // (2) do spawn { do reader.read() |data| { // (3) io::println(fmt!("Value: %?", data)); // (4) } } } do spawn { do data.write() |data| { // (5) for x in data.mut_iter() { *x = *x * 2 } // (6) } }
(1) , RWArc, (4), (6). RWArc â read() (3) write() (5) . , RWArc, . , , (2) , .
?
, , , Arc RWArc Rust. Rust , . , , . Rust unsafe, , , , malloc, free, . Rust . , , «COMPLETELY UNSAFE» .
çµè«ã®ä»£ããã«
Rust , , . , Rust -, C C++, , . , .
, , , : -, , , -, â . , .