æ°ç±³Rustaceanã®ðŸðŠã«ããðŸðŠã®ããã®Rustå ¥éãC++/C#ããã°ã©ããŒã§ãèªããããã«ãªãã
Rustã§ç°¡åãªããŒã«ãäœã£ãŠã¿ãŸãããã¯ãããŠã®TUIïŒã¢ããïŒã®ããŒã«ã§ãã
ãã®ããŒãžã§ã³0.1.0ãäœã£ãããšã§åŸãããç¥èŠããŸãšããŠã¿ãŸãã
é·æã«ãªã£ãŠããŸã£ãã®ã§ç®æ¬¡ãããŸã䜿ã£ãŠãã ãããïŒã¹ããç»é¢ã ãšäžéšã®ç®æ¬¡ãã¿ããããªããšè¡šç€ºãããªãã®ã§å°ãèŠã¥ããã§ããïŒ
ããããããããã€ãŒãããããããžãèŽããããã³ã¡ã³ãã倧æè¿ã§ãïŒ
äœæããŒã«çŽ¹ä»
ã¿ãªãããtimeã³ãã³ãã§ã³ãã³ãã®å®è¡æéãèšæž¬ããŸãããïŒRust補ã®hyperfineãšããããŒã«ããããè€æ°åå®è¡ããŠå¹³åãåºããããè€æ°ã³ãã³ããæ¯èŒã§ããã䟿å©ã§ãã
ãããèŠãŠç§ã¯ã¡ã¢ãªäœ¿çšéãèšæž¬ã§ããããããããªãšæã£ããã§ãã
ããããã®mntime
ã³ãã³ãã䜿ãã°ãå®è¡æéãšã¡ã¢ãªäœ¿çšéã®å¹³åå€ãåãããã§ãïŒ
ãããªããŒã«ã§ããRustã§äœã£ãçµç·¯ã¯ãæè¿ã¿ãŒããã«ç°å¢ãæŽããŸããããã®ãšããã¢ãã³ã§äŸ¿å©ãªããŠãã³ãã³ãã©ã€ã³ããŒã«ã«Rust補ãå€ãã®ã«æ°ä»ãããã§ããïŒç®ã®ä»ãæãããïŒïŒRustã ãšç°¡åã«ã³ãã³ãã©ã€ã³ããŒã«ãäœããããããªããïŒãšæãé£ã³ã€ããŠããŸããŸããã
ãããããããªã«é£ãããšã¯âŠããã®èŠåŽã話ãããã®ã§èšäºã«ããŸãããRuståå¿è ã®äººã¯ãã²èªãã§é£ã³è¶ããŠãã£ãŠãã ããã
èªå·±çŽ¹ä»
ç§ã¯æ®æ®µC#ã§ç€Ÿå
ããŒã«ãäœã£ãŠããŸããã¡ãã£ãšåã¯C++ã§ã²ãŒã ãäœã£ãŠããããŠãŸããã
PythonãJavaScriptãããŸã«äœ¿ããŸãããïŒãã¡ã€ã«ã ãã®ã¡ãã£ãšããã¹ã¯ãªãããããã§ãã
ä»åã®ãããžã§ã¯ãã¯Rust, TUI, Git, GitHub, OSSãšæ¬æ Œçã«äœãã®ã¯ãããŠã®ç°å¢ã§ããããèŠåŽããŸãããããããŸã ç解ããŠãªãæ©èœãå€ãã®ã§ä»ãèŠåŽããŠããŸãã
ãšã¯ãããæµè¡ã£ãŠããç°å¢ãªã®ã§æŽåããã£ãããããŠããŠæå¿ããããšãå€ããããžã§ã¯ãã§ããã
ãšããããšã§ãç§ãC++,C#ããã°ã©ããŒã®èŠç¹ã§Rustã®åºæ¬ãæžããŠã¿ãŸãã
åèæç®
- å®è·µRustããã°ã©ãã³ã°å ¥é
- The Rust Programming Language æ¥æ¬èªç
- æšæºã©ã€ãã©ãª API Reference
- ã¯ã¬ãŒããªããžããª
éçºç°å¢
ä»åã¯Rust v1.63.0ã䜿ã£ãŠéçºãããŸããã
ãã·ã³ã¯Mac mini M1ã䜿ãããšãã£ã¿ã¯Visual Studio Code(VSCode)ã§ãRustçšã«æ¬¡ã®æ¡åŒµæ©èœãã€ã³ã¹ããŒã«ããŠãŸãã
- CodeLLDB: ãããã¬
- rust-analyzer: Rustã³ãŒãäœæè£å©ïŒæã¯rust-lang.rustã䜿ãããŠããããïŒ
ã§ã¯å眮ããé·ããªããŸããããmntime
ã³ãã³ãã®ããŒãžã§ã³0.1.0ãäœãã®ã«å©çšããæ©èœã玹ä»ããŠãããŸãã
çšèªé
-
Rustacean
ïŒã©ã¹ãã€ã·ã£ã³ïŒ: Rustãæžã人ã®ããšãCrustacean
ïŒç²æ®»é¡ïŒãèªæºã§ãããã«ãã®ã¢ã€ã³ã³ã䜿ããããïŒå ¬åŒã¢ã€ã³ã³ã¯èªè»¢è»ã®ã®ã¢ïŒ -
Edition
ïŒãšãã£ã·ã§ã³ãçïŒ: Rustã®å€§èŠæš¡å€æŽããŒãžã§ã³ãåã¯ã¬ãŒããå¥ã®Editionã§ããã«ããã§ããã -
cargo
ïŒã«ãŒãŽãç©ã¿è·ïŒ: Rustã®ãã«ãããŒã«ãããã±ãŒãžç®¡çããŒã«ã§ãããµãã³ãã³ãã§ãããããªæ©èœãããã -
crate
ïŒã¯ã¬ãŒããæšç®±ïŒ: ã©ã€ãã©ãªãäž»ã«crates.ioã§å ¬éãããŠããã -
module
ïŒã¢ãžã¥ãŒã«ãéšåã®éãŸãïŒ: C#ã§ããnamespaceã®ãããªãã®ã -
trait
ïŒãã¬ã€ããç¹åŸŽïŒ: C#ã§ããã€ã³ã¿ãã§ãŒã¹ã®ãããªãã®ã -
derive
ïŒãã£ã©ã€ããå°ãåºãïŒ: ãã¯ãã®ïŒçš®ã§ã³ãŒãã®åå®çŸ©ããå¥ã®ã³ãŒããèªåçæãããããtraitã®æŽŸçãèªåå®è£ ãããšãã«äœ¿ãããã -
attribute
ïŒã¢ããªãã¥ãŒããå±æ§ïŒ: ãã¯ãã®ïŒçš®ã§åå®çŸ©ä»¥å€ïŒé¢æ°ããã£ãŒã«ããªã©ïŒããå¥ã®ã³ãŒããèªåçæãããããtestã§äœ¿ãããã -
panic
ïŒãããã¯ãæ ãïŒ: ã¹ã¬ããã匷å¶çµäºãããã -
unwrap
ïŒã¢ã³ã©ãããå è£ ã解ãïŒ: æ£åžžå€ãæåŸ ããŠå±éãããç°åžžå€ãªããããã¯ãçºçã -
let
ïŒã¬ãããä»®ã«ããšãããã貞ãïŒ: å€æ°å®£èšãå€æ°ã«å€ãæçžããã
é·ããªã£ãã®ã§èŠçŽ
C++/C#ãç¥ã£ãŠãã人åãã®ãšãããããœãŒã¹ã³ãŒããèªãã®ã«å¿ èŠãªæäœéã®ç¥èããŸãšããŸãã
-
cargo
ã³ãã³ãããã«ãã·ã¹ãã å Œããã±ãŒãžãããŒãžã£ãŒã§ãããã«ãã¯cargo build
ãããã¯cargo run
ã§è¡ããcargo add
ã§ã©ã€ãã©ãªïŒã¯ã¬ãŒãïŒãè¿œå ã§ããŸãã -
Cargo.toml
ãã¡ã€ã«ã«æžãããã©ã€ãã©ãªïŒã¯ã¬ãŒãïŒãèªåã§ãªã³ã¯ããŠãããŸãã - ãœãŒã¹ã³ãŒãåå²ããã«ã¯ã
mod <ã¢ãžã¥ãŒã«å>
ã䜿ã£ãŠäœ¿çšãããã¡ã€ã«ïŒã¢ãžã¥ãŒã«ïŒãæ瀺ããå¿ èŠããããŸãã -
use <ãã¹>
ã§åå解決ãçç¥ã§ããŸãããã¹æå®ã¯ã¯ã¬ãŒãå::ã¢ãžã¥ãŒã«å::察象
ã®åœ¢ã§ãããã®éãself::
ã¯èªåã®éå±€ãè¡šããsuper::
ã¯ã²ãšã€äžã®éå±€ãè¡šããŸããæ®éã®ãã¹æå®ã®.
ãš..
ã®ãããªãã®ã§ãããŸãcrate::
ã¯ããã°ã©ã ã®ã«ãŒãéå±€ãè¡šããŸãã - å€æ°å®£èšã¯
let
ïŒäžå€ïŒ/let mut
ïŒå€æŽå¯ïŒã§è¡ããŸãã&
ã§åç §ã*
ã§éåç §ãã§ããŸããåæšè«ãããããããããªå Žæã§åãçç¥ã§ããŸãã - åºæ¬åã®å€æ°ã¯ã³ããŒæž¡ã/ä»£å ¥ã§ãããäžè¬çã«ã¯ã ãŒãæž¡ã/ä»£å ¥ã§ãã
- å€æ°ã¯éåžžã¹ã¿ãã¯é åã«ã®ããŸããã
Box<T>::new(123)
ãšãããšããŒãé åã«ã®ããŸãã - åæå
enum
ã¯å€ããšã«ãå¥ã ã®å€æ°ãä¿æã§ããŸãã -
if let Some(x) { println!({x}) }
ãmatch expr { Ok(x) => {println!({x})}, Err(_) => {panic!()}}
ã®ãããªãã¿ãŒã³ããããã§ããŸãã- æšæºã§ãã䜿ãåæåãïŒã€ããã
Option<T>
ãSome(_)
ãšNone
æã¡ãResult<T,E>
ãOk(_)
ãšErr(_)
ãæã£ãŠããŸãã -
Result<>
åŒã¯?
ãã€ãããšErr(_)
æã«æ©æreturn Err(_)
ããŠãããŸããOption<>
ãåæ§ã«Noneãæ©æãªã¿ãŒã³ã§ããããŸããSome(x)
ãOK(x)
ã®x
ãåãåºãã®ã«ãunwrap()
ããã䜿ãããŸãããNone
ãErr(_)
ã®å Žåpanic!()
ãçºçããŸãã
- æšæºã§ãã䜿ãåæåãïŒã€ããã
- classã¯ãªã
struct
ã®ã¿ã§ãã¡ã³ããŒé¢æ°ã¯impl æ§é äœå { fn func(&self){} }
ã§å®çŸ©ããŸãã - ç¶æ¿ã¯
trait
ãinterface / abstructã®ãããªæãã§ãimpl ãã¬ã€ãå for æ§é äœå { }
ã§å®è£ ããŸãã - ã¯ããŒãžã£ã¯
|arg,arg2| {ã}
ã®åœ¢ã§ãã - ãã¯ãã¯
!
ã§çµãããŸããåŒã³åºãã¯macro!(ã)
ãmacro![ã]
ãmacro!{ã}
ã©ãã§ãããã§ããå®çŸ©ã¯macro_rule!
ãå©çšããŸãã -
#[ã]
ã¢ããªãã¥ãŒãã§ããŸããŸãªä¿®é£ŸããããŸãã
ããããã以éã§å°ã詳现ã«èª¬æããŠããŸãã
cargoã®äœ¿ãæ¹
cargoãšããRustãšã³ã·ã¹ãã ã®ããã®ããŒã«ãæšæºã§ä»ããŠããŸãããããããã±ãŒãžç®¡çããã«ãããã¹ããããã¥ã¡ã³ãçæãªã©ããããããªããŠãããäœã§ãå±ã§ãããã®cargoã®æ©èœããç§ã䜿ã£ããã®ã玹ä»ããŸãã
ãããžã§ã¯ãäœæ
cargo new <path>
# ãã§ã«ãã©ã«ãããããªã
cargo init [path]
<path>
ã«Rustãããžã§ã¯ããäœæããŸããCargo.tomlãã¡ã€ã«ãsrcãã©ã«ããäœãããŸããããã©ã«ãã¯ã¢ããªçšãã³ãã¬ãŒãã䜿çšããŸããã--lib
ãªãã·ã§ã³ãæå®ããããšã©ã€ãã©ãªçšãã³ãã¬ãŒãã䜿ãããŸãã
ããŒã«ã€ã³ã¹ããŒã«
cargo install <crate> ...
# ã¢ã³ã€ã³ã¹ããŒã«
cargo uninstall <crate> ...
crates.ioãã<crate>
ãã€ã³ã¹ããŒã«ããŸããããã©ã«ãã€ã³ã¹ããŒã«å
ã¯$HOME/.cargo/bin
ã§ãã<crate>
ã¯--git <URL>
ã§GitHubãªã©GitãªããžããªãçŽæ¥æå®ãããã--path <PATH>
ã§ããŒã«ã«ã®ãã¹ãçŽæ¥æå®ãããã§ããŸãã
ä»ã®ãšããç§ã¯æ¬¡ã®ãã®ãã€ã³ã¹ããŒã«ããŠããŸãã
-
cargo-audit:
cargo audit
ã§ã»ãã¥ãªãã£è匱æ§å ±åã®ãã£ãã¯ã¬ãŒãããŒãžã§ã³ã䜿çšããŠããã確èªã§ããŸãã -
cargo-expand:
cargo expand
ã§ãã¯ããå±éããŠç¢ºèªã§ããŸãã -
cargo-license:
cargo license
ã§äŸåã¯ã¬ãŒãã®ã©ã€ã»ã³ã¹åã衚瀺ããŸãã-
README.mdçšã«ãã€ãåºåãã®ããŒãã«åºåããã¯ã³ã©ã€ããŒ
# çŽæ¥äŸåããŠãããã®ã ããªã¹ãã¢ãã cargo license --direct-deps-only --avoid-build-deps --avoid-dev-deps | awk -F ":" 'BEGIN {printf "|License|crate|\n|-|-|\n"} {printf "|%s|%s|\n", $1, $2}' # åèµ·çã«äŸåããŠãããã®ãå«ããŠãªã¹ãã¢ãã cargo license --avoid-build-deps --avoid-dev-deps | awk -F ":" 'BEGIN {printf "|License|crate|\n|-|-|\n"} {printf "|%s|%s|\n", $1, $2}'
-
-
cargo-trend:
cargo trend <crates> ...
ã§ã¯ã¬ãŒãã®ããŠã³ããŒãæ°ãtrend.svgãã¡ã€ã«ã«ã°ã©ãåããŠãããŸãã--relative
ãªãã·ã§ã³ã§æ°ã§ã¯ãªãæ¯çã§ã°ã©ãåã§ããŸãã
ã¯ã¬ãŒãæ€çŽ¢
cargo search <query>
crates.ioããã¯ã¬ãŒããæ¢ããŸãã
ã¯ã¬ãŒãè¿œå
cargo add <DEP> ...
äŸåã¯ã¬ãŒããCargo.tomlãã¡ã€ã«ã«è¿œå ããŸãã--git
ã--path
ã--registry
ãªãã·ã§ã³ã§ã¯ã¬ãŒãæ€çŽ¢å Žæãæå®ã§ããŸãã--features <FEATURES>
ã§è¿œå ããã¯ã¬ãŒãã®æ©èœãéžæå¯èœã§ãããŸãã--dev
ã§testsãexamplesãbenchmarksçšã«ã€ã³ã¹ããŒã«ãããã--build
ã§ãã«ãã¹ã¯ãªããçšã«ã€ã³ã¹ããŒã«ã§ããŸãã
ã¯ã¬ãŒãäŸåé¢ä¿ç¢ºèª
cargo tree
ããªãŒåœ¢åŒã§äŸåã¯ã¬ãŒãã衚瀺ã§ããŸãã
ãã«ããã§ãã¯
cargo check
ãœãŒã¹ã³ãŒãã解æããŠãã«ããšã©ãŒã確èªããŸãããã€ããªçæãŸã§ãããªãã®ã§buildããé«éã§ãã
ãã«ã
cargo build
ãœãŒã¹ã³ãŒãããã«ãããŸãã--release
ãªãã·ã§ã³ã§æé©åã®ããã£ããªãªãŒã¹ã¢ãŒãã§ãã«ãããŸããbuildã³ãã³ãã¯ããŸã䜿ãããæ®æ®µã¯åŸè¿°ã®çŽæ¥å®è¡ã䜿çšããŸãã
å®è¡
cargo run -- [args] ...
ãœãŒã¹ã³ãŒãããã«ãããŠå®è¡ããŸãã--
ã§åºåã£ãåŸã®åŒæ°ãå®è¡ãã¡ã€ã«åŽã®ãªãã·ã§ã³ã«ãªããŸãã--example [<NAME>]
ã§examples/ãã©ã«ãäžã®<NAME>
ããã«ãïŒå®è¡ã§ããŸãã
ãã¹ã
cargo test
ãã¹ããå®è¡ããŸãããœãŒã¹ã³ãŒãäžã®#[test]
ã¢ããªãã¥ãŒãã®ã€ããé¢æ°ã ãã§ãªããããã¥ã¡ã³ãã³ã¡ã³ãäžã®ã³ãŒãããã¹ãããŠãããŸãã
ããã¥ã¡ã³ãäœæ
cargo doc
ãœãŒã¹ã³ãŒãã«æžããããã¥ã¡ã³ãã³ã¡ã³ãããããã¥ã¡ã³ããäœæããŸãã--open
ãªãã·ã§ã³ã§çæãããã®ããã©ãŠã¶ã§éããŠãããŸããïŒSafariã ãšæ£ãã衚瀺ãããªãã£ãã®ã§ãChromeã§éãçŽããŠèŠãŠãŸããïŒ
ãœãŒã¹ã³ãŒããã©ãŒããã
cargo fmt
ãœãŒã¹ã³ãŒãããã©ãŒãããããŠãããŸãã
ãœãŒã¹ã³ãŒãåæ
cargo clippy
ãœãŒã¹ã³ãŒããåæããŠãããŸããããããLinterã§ãã--fix
ãªãã·ã§ã³ã§èªåä¿®æ£ã§ãããã®ã¯å¯Ÿå¿ããŠãããŸãã
åé€
cargo clean
cargoãçæãããã¡ã€ã«ãã¡ãåé€ããŸãã
crates.ioã«ã¯ã¬ãŒããå ¬é
cargo login
cargo publish
cargo publish
ã§å
¬éããã«ã¯äºåã«æ¬¡ã®äœæ¥ãå¿
èŠã§ãã--dry-run
ãªãã·ã§ã³ã§ãã§ãã¯ã ãèµ°ããŸãã
- Cargo.tomlã«å¿ èŠãªæ å ±ãæžã
- crates.ioã§ã¢ã«ãŠã³ããäœæãAPIããŒã¯ã³ãæºåãã
-
cargo login
ã§ãã°ã€ã³ããããã®ãAPIããŒã¯ã³ãä¿åãã
å
¬éããããªããã®ã¯Cargo.tomlã«publish=false
ãæžããŠãããšééããŠå®è¡ããŠããšã©ãŒã«ãªããŸãã
詳ããã¯Crates.ioã«ã¯ã¬ãŒããå ¬éãããåç §ãã ããã
Cargo.tomlã«ã€ããŠ
Cargo.tomlã«ããã±ãŒãžã®ã¡ã¿æ å ±ãæžãããŠããŸãã詳ããã¯The Manifest Formatãåç §ãã ããã
[package]
ã»ã¯ã·ã§ã³
ãããžã§ã¯ãã®ååãããŒãžã§ã³ãREADMEã®å Žæãªã©ã§ãcrates.ioã«å ¬éãããšãã«ãããã®æ å ±ã䜿ãããŸãã
[dependencies]
ã»ã¯ã·ã§ã³
ããã±ãŒãžã«å¿
èŠãªäŸåã¯ã¬ãŒããæžããŸããcargo add
ã§è¿œå ãã§ããŸãããçŽæ¥è¿œèšããŠãããã§ãã
[dev-dependencies]
ã»ã¯ã·ã§ã³
testsãexamplesãbenchmarksçšã«å¿
èŠãªäŸåã¯ã¬ãŒããæžããŸããcargo add --dev
ã§è¿œå ã§ããŸãã
[build-dependencies]
ã»ã¯ã·ã§ã³
ãã«ãã¹ã¯ãªããçšã«å¿
èŠãªäŸåã¯ã¬ãŒããæžããŸããcargo add --build
ã§è¿œå ã§ããŸãã
Cargo.lock
ãã«ããããšCargo.tomlã®dependenciesã«ããšã¥ããŠã¯ã¬ãŒããããŠã³ããŒãããããã®ããŒãžã§ã³ãCargo.lockã«èšèŒãããŸããCargo.lockãã¡ã€ã«ã¯å®è¡ãã¡ã€ã«ãããžã§ã¯ããªãããŒãžã§ã³ç®¡çã«è¿œå ããã©ã€ãã©ãªãããžã§ã¯ããªãããŒãžã§ã³ç®¡çããignoreããã®ãããããã§ãã
ãœãŒã¹ã³ãŒãåå²
Rustã¯ãã€ããªãããžã§ã¯ããªãsrc/main.rsãã©ã€ãã©ãªãããžã§ã¯ããªãsrc/lib.rsããããããšã³ããªãŒãã€ã³ãã®ãã¡ã€ã«ã§ããç¹ã«æå®ããªããã°ãã®ïŒãã¡ã€ã«ã®ã¿ããã«ããããŸãã
åçŽãªã¹ã¯ãªããåŠçã§ãªããã°ãè€æ°ã®ãã¡ã€ã«ã«åããŠç®¡çããããšã«ãªãã§ãããããã®å Žåã¢ãžã¥ãŒã«ãšããŠåå²ããŸãã
åããã¡ã€ã«å ã§ã¢ãžã¥ãŒã«ãåãã
fn my_func() {
println!("Hello, world!");
}
fn main() {
my_module::hoge(); // äžå±€ãžã®ã¢ã¯ã»ã¹ã¯`ã¢ãžã¥ãŒã«å::`
}
mod my_module {
pub fn hoge() {
super::my_func(); // äžå±€ãžã®ã¢ã¯ã»ã¹ã¯`super::`
}
}
ãã®ããã«ããã¡ã€ã«å
ã«mod <ã¢ãžã¥ãŒã«å> {ã}
ãšæžããšã¢ãžã¥ãŒã«ãå®çŸ©ã§ããŸããå
¥ãåã®å Žåãäžå±€ããäžå±€ã¯super
ã䜿ã£ãŠã¢ã¯ã»ã¹ã§ããŸããäžå±€ããäžå±€ã®å Žåã¯<ã¢ãžã¥ãŒã«å>
ã§ã¢ã¯ã»ã¹ã§ããŸãããpub
ãšããpublicãªãã®ã ãã§ãã
ã¡ãªã¿ã«pub(<å
¬éç¯å²>)
ã§ç¯å²ãæå®ã§ããŸãã
-
pub(in <path>)
: æå®ã®ãã¹ã«å ¬é -
pub(self)
: åãã¢ãžã¥ãŒã«å ã«å ¬é -
pub(super)
: 芪ã¢ãžã¥ãŒã«å ã«å ¬é -
pub(crate)
: åãã¯ã¬ãŒãå ã«å ¬é
åãã©ã«ãå ã§ã¢ãžã¥ãŒã«ãåãã
ð src
âââ main.rs
âââ my_module.rs
fn my_func() {
println!("Hello, world!");
}
fn main() {
my_module::hoge();
}
// 解æãããmain.rsã§ã¢ãžã¥ãŒã«åå²å®£èšããã
// ãããç¡ããšmy_module.rsã¯è§£æãããªã
mod my_module;
// mod {ã}ã§å²ãŸãªãïŒãã¡ã€ã«åãã¢ãžã¥ãŒã«åã«ãªãïŒ
pub fn hoge() {
super::my_func();
}
ãã¡ã€ã«åå²ããã ãã§ã¯ãã«ã察象ã«è¿œå ããããmain.rsã§mod ã¢ãžã¥ãŒã«å;
ãšå®£èšããªããšãããªããæåã¯ãããæžããªããŠããŸããã«ãã§ãããå€éšã¯ã¬ãŒãåããŠæ«å®å¯Ÿå¿ããŠããïŒãããã§throbber-widgets-tuiãäœãããïŒ
åãã©ã«ãã«ã¢ãžã¥ãŒã«ãåããïŒ2018ãšãã£ã·ã§ã³ã§è¿œå ãããããŒãžã§ã³ïŒ
ð src
âââ main.rs
âââ my_module.rs // åãã©ã«ããšåå
âââ ð my_module
âââ bar.rs
âââ foo.rs
fn my_func() {
println!("Hello, world!");
}
fn main() {
my_module::bar::hoge(); // éå±€æå®ãïŒã€æ·±ããªã£ã
}
mod my_module;
// ãã©ã«ãåãšåããã¡ã€ã«å.rsãäœæ
pub mod bar; // äžå±€ãã©ã«ãå
ã®ãã«ã察象ãã¡ã€ã«ãåæãã
mod foo; // pubããªããŠãåãéå±€ïŒããã ãšbar)ããã¯ã¢ã¯ã»ã¹ã§ãã
// modã ãã§ãªã
pub fn foo() {
// ããã«ãå®çŸ©ãæžãã
}
// å¥ã®ã¢ãžã¥ãŒã«ããŸãã§ããã§å®çŸ©ããããã«å
¬éã§ãã
// crate::foo::fuga()ã§ãªããcrate::fuga()ã§ã¢ã¯ã»ã¹ã§ãã
pub use self::foo::fuga;
pub fn hoge() {
super::foo::fuga(); // åãéå±€ã¢ãžã¥ãŒã«ãžã®ã¢ã¯ã»ã¹
}
pub fn fuga() {
crate::my_func(); // super::super::ã§ãããããæäžå±€ã¯crate::ã§ã¢ã¯ã»ã¹ã§ãã
}
ãã©ã«ããšååã®ãã¡ã€ã«ãçšæãããšããµãã¢ãžã¥ãŒã«ãšããŠãã©ã«ãã䜿çšã§ããŸãã
åãã©ã«ãã«ã¢ãžã¥ãŒã«ãåããïŒæããããããŒãžã§ã³ïŒ
ð src
âââ main.rs
âââ ð my_module
âââ bar.rs
âââ foo.rs
âââ mod.rs // ãµãã¢ãžã¥ãŒã«ã®ãšã³ããªãŒãã€ã³ã
2018ãšãã£ã·ã§ã³çãšã ãããåãã§ãããmy_module.rsãã¡ã€ã«ãmy_module/mod.rsãã¡ã€ã«ã«ãªã£ãŠããŸãã
ãã®æ¹åŒã ãšè€æ°ãµãã¢ãžã¥ãŒã«ã®ãã©ã«ãããããšãšãã£ã¿ã§å€æ°ã®mod.rsãã¡ã€ã«ãéãããŠçŽããããããæ°ããæ¹åŒãè¿œå ãããŸããããšã¯ãããïŒã€ã®ãã©ã«ãã«ãŸãšãŸã£ãŠãããšããå©ç¹ãããã®ã§åŒãç¶ããã¡ãã®æ¹åŒã䜿ãããŠããŸããïŒãã©ã«ãäžã§mod.rsãããªããŠãã©ã«ãåãšååãã¡ã€ã«ã眮ããã°è¯ãã£ãã®ã«ããªãã§ïŒéå±€äžã«çœ®ãå¿
èŠããã£ããã ããããïŒ
ã¯ã¬ãŒãåå²
ð src
âââ main.rs
âââ ð my_crate // ç¬ç«ããã©ã€ãã©ãªïŒå Žæã¯ã©ãã§ãããïŒ
âââ Cargo.toml
âââ ð src
âââ lib.rs // ã©ã€ãã©ãªã®ãšã³ããªãŒãã€ã³ã
ãœãŒã¹ã³ãŒãåå²ããå³å¯ã«æš©éãåããã«ã¯ãå¥ã©ã€ãã©ãªãšããŠã¯ã¬ãŒãåå²ãããŸãã
# ã¯ã¬ãŒãäœæ
cargo new --lib my_crate
# äœæããã¯ã¬ãŒãã®å©çšç³è«
cargo add --path my_crate
fn main() {
my_crate::add(1, 2);
}
pub fn add(left: usize, right: usize) -> usize {
left + right
}
ã¯ã¬ãŒãã®äœæå Žæã¯ä»åsrc/é
äžã«ããŠããŸãããã©ãã§ãïŒãããžã§ã¯ãå€ã§ãïŒããã§ããã©ã€ãã©ãªã®ãšã³ããªãŒãã€ã³ãã¯lib.rs
ãšãªã£ãŠããŸãã
ãããŠäœ¿çšããåŽã§cargo add --path
ãšãããšããŒã«ã«ã®ãã¡ã€ã«ãCargo.tomlã®[dependencies]ã«è¿œå ã§ããŸããcargo add --git
ã ãšGitãªããžããªïŒGitHubãšãïŒãæå®ã§ããã®ã§ãcrates.ioã§å
¬éããªããŠã䜿çšã§ããŸãã
åŒã³åºãã¯ã¯ã¬ãŒãå::*
ãšæå®ããŸãããããã¯ã¬ãŒãåŽãã¢ãžã¥ãŒã«ã«å¥ããŠããå Žåmy_crate::my_module::my_func
ã®ããã«æå®ããŸãã
use
Rustã«ã¯use <path>
ãšãããC++ã®using namespace
ã®ãããªãã®ããããŸãã
ã¢ãžã¥ãŒã«ãã¯ã¬ãŒãã®éå±€ãæ·±ããªããšæ¯åãã«ãã¹ã§æžããšåé·ã«ãªã£ãããå¥ã®ã¯ã¬ãŒããšç°¡åã«å·®ãæ¿ããããããã«ããããšãå©çšããŸãã
fn my_func() {
println!("Hello, world!");
}
fn main() {
use my_module::hoge;
hoge(); // my_moduleã®hogeã䜿çšãã
}
mod my_module {
pub fn hoge() {
super::my_func();
}
}
ãã¹ãçç¥ã§ããã ãã§ãªããas ãšã€ãªã¢ã¹å
ãä»äžãããšå¥åãã€ããããšãå¯èœã§ãã
fn main() {
use my_module::hoge as my_hoge; // å¥åãã€ãã
my_hoge(); // my_moduleã®hogeã䜿çšãã
}
ãã¹ã®çç¥ã ãã§ãªãããã¬ã€ãã®å©çšã«ãuse <path>
ã®æå®ãå¿
èŠãªãšãããããŸããïŒãã¡ããšç解ã§ããŠãŸãããïŒãã®å Žåçç¥ã¯äžèŠã§ããã°as _
ãšã¢ã³ããŒã¹ã³ã¢ã䜿ããšæ£ããåç
§ãã€ã€ãçç¥ã§ããªãç¶æ
ã«ã§ããŸãã
use rand::Rng as _; // ã°ããŒãã«ã«ãæžãã
fn main() {
let mut rng = rand::thread_rng();
rng.gen()
}
ãŸãã{ã}
ã䜿ãã°ãè€æ°åæã«æå®ã§ããŸãã
use my_crate::{hoge as _, module_foo::bar};
以äžãåºæ¬çãªuse
ã®äœ¿ãæ¹ã§ãããããŸã«extern crate
ããŒã¯ãŒããèŠãããšããããŸããããã¯æã®æžãæ¹ã§ãä»ã¯ïŒå²ïŒåã®å Žé¢ã§å¿
èŠãªããªã£ããããã§ãã
å€æ°
let / let mut
Rustã®å€æ°å®£èšã¯let
ã䜿çšããŸããããã©ã«ãã ãšå€æŽäžå¯ïŒimmutableïŒã§ããletã¯ãïŒããããããšãïŒããããïŒã¢ããŒããªã©ã®äžåç£ãïŒè²žããä»®ã«ããšãããããªã©ã®æå³ããããŸããbindingïŒæçžïŒãšãèšããŸãã
let x = 1;
x = 2; // ãã«ããšã©ãŒãå€æŽäžå¯
let x = 2; // åå®çŸ©ã¯ã§ãã
let mut
ãšãããšå€æŽå¯ïŒmutableïŒã«ãªããŸãã
let mut x = 1;
x = 2; // å€æŽã§ãã
let x = x; // åå®çŸ©å¯èœïŒlet mutãOKïŒ
åæå®ãã§ããŸãã
let x: i32 = 1;
let x: f64 = 2.0; // æµ®åå°æ°åã¯å°æ°ç¹å¿
é ïŒ`2.`ã§ãOKïŒ
const
constã§å®æ°ã宣èšã§ããŸããä»ã®ãšããconstã¯åæå®ãçç¥ã§ããŸãããconstã¯å€§æåã䜿ãã®ãæšå¥šãããŠããŸãã
const X: i32 = 1;
const X: f64 = 2.0; // ãã«ããšã©ãŒãletãšéãååã¯åãã¹ã³ãŒãå
ã§ã¯äœ¿ããªã
let y = 2;
const Y: i32 = y; // ãã«ããšã©ãŒãconstã¯ãã«ãäžã«åããå®æ°ãã代å
¥ã§ããªã
static
staticã§ããã°ã©ã å®è¡äžçåãç¶ããå€æ°ã宣èšã§ããŸããconståæ§ã«åæå®ãçç¥ã§ããŸãããã倧æåã䜿ãã®ãæšå¥šãããŠããŸãã
static X: i32 = 1;
static X: f64 = 2.0; // ãã«ããšã©ãŒãletãšéãååã¯åãã¹ã³ãŒãå
ã§ã¯äœ¿ããªã
let y = 2;
const Y: i32 = y; // ãã«ããšã©ãŒãstaticã¯ãã«ãäžã«åããå®æ°ãã代å
¥ã§ããªã
static mut Z: i32 = 2; // mutã§å€æŽå¯èœã«ãªãããåç
§ããå Žæãã¹ãŠunsafeæäœã«ãªã
unsafe { Z = 3; }
once_cell (lazy-static)
staticããã«ãäžã«åããå®æ°ãã代å
¥ã§ããªãã®ã¯äžäŸ¿ã§ãã®ã§ãåçå€æ°ãèšå®ã§ãããã°ã©ã å®è¡äžçåãç¶ããå€æ°ã䜿ããããã«ããã¯ã¬ãŒãããããŸãã
æãã䜿ãããŠããã®ã¯lazy-staticã§ãããæè¿ã¯OnceCellã«çœ®ãæãã£ãŠããŠããŸããOnceCellãæšæºå
¥ãããïŒ
fn main() {
use once_cell::sync::OnceCell;
let mut x = 2;
static X: OnceCell<i32> = OnceCell::new();
let y = *X.get_or_init(|| x);
println!("{}", y); // => 2
x = 3;
let y = *X.get_or_init(|| x); // ïŒåç®ä»¥éã¯åæåæžã¿ã®å€ãååŸãã
println!("{}", y); // => 2
}
// é¢æ°å
staticå€æ°ã«ããŠè¿ãã®ãè¯ã
fn hoge() -> i32 {
static hoge: OnceCell<i32> = OnceCell::new();
*hoge.get_or_init(|| 1)
}
å€æŽå¯èœãªstaticãå®çŸ©ãããå Žåã¯ãOnceCellãšMutexãçµã¿åãããŸããstaticã¯ã¹ã¬ããã»ãŒãã«ããå¿ èŠããããCell<_>ã䜿ããŸããã
fn main() {
use once_cell::sync::OnceCell;
static X: OnceCell<std::sync::Mutex<i32>> = OnceCell::new();
X.set(std::sync::Mutex::new(1)); // åæå
println!("{}", *X.get().unwrap().lock().as_ref().unwrap()); // => 1
*X.get().unwrap().lock().unwrap() = 2; // åæåããMutexãååŸãããã®å€ãå€æŽ
println!("{}", *X.get().unwrap().lock().as_ref().unwrap()); // => 2
}
åç §
åºæ¬åãé€ãRustã¯ã ãŒãã»ãã³ãã£ã¯ã¹ãããã©ã«ããšãªã£ãŠãŸããé¢æ°åŒã³åºãã®ãã³ã ãŒãããŠãããšãããžããªã®ã§åç
§ã®ããã¿ããããŸãã
&
ã§åç
§ãè¡šããŸãããããborrowingïŒåçšïŒãšèšããã ãŒãã»ãã³ãã£ã¯ã¹ã¯ownershipïŒæææš©ïŒã®ç§»åãšãªããŸãã
fn puts(msg: String) {
println!("{}", msg);
}
fn puts_ref(msg: &String) {
println!("{}", msg);
}
fn main() {
let msg = "hoge".to_string();
puts_ref(&msg);
puts_ref(&msg);
puts(msg);
puts(msg); // ãã«ããšã©ãŒãã ãŒãæžã¿å€æ°ã®åç
§
}
&mut
ã§å€æŽå¯èœãªåç
§ãã§ããŸãããã ãã&
å«ããŠãã ïŒã€ã®ã¿ããåç
§ã§ããŸããã
fn main() {
let mut msg = "hoge".to_string();
{
let x = &msg;
}
{
let mut y = &mut msg;
y.insert_str(0, "foo.");
}
println!("{}", msg); //=> foo.hoge
let u = &msg;
let w = &mut msg; //ãã«ããšã©ãŒãå¯å€åç
§ã¯ãã ïŒã€ã®ã¿ååšã§ãã
msg = "bar".to_string(); //ãã«ããšã©ãŒãåç
§ã§è²žãåºããŠãïŒborrowedïŒã®ã§å€æŽäžå¯
println!("{}", u);
}`
ã©ã€ãã¿ã€ã
å€æ°ã«ã¯æå¹ãªæéãããã©ã€ãã¿ã€ã ãšèšããŸããDropãã¬ã€ããå®è£ ããŠãããšã©ã€ãã¿ã€ã ãå°œãããšãã«drop()ãåŒã³åºãããŸãã
struct My {
msg: &'static str
}
impl Drop for My {
fn drop(&mut self) {
print!("{},", self.msg);
}
}
fn main() {
let a = My { msg: "a" };
let b = My { msg: "b" };
{
let c = My { msg: "c" };
}
}
//=>
// c,b,a,
ããã®a
, b
, c
ãåç
§ã§åçšããŠã¿ãŸãã
fn main() {
let a = My { msg: "a" };
let b = My { msg: "b" };
let mut x = &a;
x = &b;
{
let c = My { msg: "c" };
x = &c; // xã®ã©ã€ãã¿ã€ã ãcã®ã©ã€ãã¿ã€ã ããé·ããããã«ããšã©ãŒ
}
x; // ãã®è¡ãæ¶ããšãã«ãã§ãã
}
äžèšã³ãŒãã ãšãx
ã®ã©ã€ãã¿ã€ã ãmainé¢æ°ã®çµäºãŸã§ãããŸãããc
ã®ã©ã€ãã¿ã€ã ãé¢æ°å
ã¹ã³ãŒãã ããšçããªã£ãŠããŸãããã®ããã«åçšããåŽã®æ¹ãé·çãããã®ã¯ã§ããŸãããããããRust 1.32以éãªãæåŸã®è¡ã®x;
ãåé€ãããšãã«ããã§ããŠããŸããŸããããã¯çŸåšã®Rustã¯ã¬ãã·ã«ã«ã¹ã³ãŒãã«ãããªãã©ã€ãã¿ã€ã ïŒNLL, None Lexical LifetimeïŒã§ããåçšãã§ãã«ãŒãå°å
¥ãããŠããŠãæåŸã«äœ¿çšãããšãããŸã§ã§ã©ã€ãã¿ã€ã ãå°œããããã«ãªããŸããã
ãšããã§struct My
ã®ãã£ãŒã«ãã«&'static str
ãšããåæå®ããããŸããããã¯ã©ã€ãã¿ã€ã ã'static
ïŒããã°ã©ã å®è¡äžãã£ãšæå¹ïŒãª&str
ãè¡šããŠããŸãã'static
ã¯ç¹æ®ãªã©ã€ãã¿ã€ã 泚éã§ããéåžžã¯<'ã>
ã䜿ã£ãŠå®£èšããå¿
èŠããããŸãã
// ãã®é¢æ°ã®è¿ãå€ã®ã©ã€ãã¿ã€ã ã¯åŒæ°ã®ã©ã€ãã¿ã€ã ïŒçãæ¹ãé©çšãããïŒãšåã
fn which<'a>(x: &'a str, y: &'a str) -> &'a str {
if x == y {
x
} else {
y
}
}
fn main() {
let mut x = "x";
{
let msg = "msg".to_string();
x = which("hoge", msg.as_str()); // ãã«ããšã©ãŒã
// "hoge"ã¯staticãªã©ã€ãã¿ã€ã ã§ãmsgã¯ãã®ã¹ã³ãŒãå
ã ããªã®ã§ã
// çãmsgãšåãã©ã€ãã¿ã€ã ãè¿ã£ãŠãã
}
//ãã®è¡ãæ¶ãã°åçšãã§ãã«ãŒãããæãã«å€æããŠããã«ããšã©ãŒããªããªã
println!("{}", x);
}
å
æ°å€å
Rustã®ã¹ã«ã©ãŒåã®æŽæ°ãæµ®åå°æ°ã¯ããããµã€ãºã䜿ã£ãŠè¡šããŸãã
- 笊å·ä»ãæŽæ°:
i8
,i16
,i32
,i64
ããã€ã³ã¿ãµã€ãºã«äŸåããisize
- 笊å·ãªãæŽæ°:
u8
,u16
,u32
,u64
,usize
- æµ®åå°æ°:
f32
,f64
æŽæ°ãªãã©ã«ã®åºæºã¯i32
ã§ãæµ®åå°æ°ãªãã©ã«ã®åºæºã¯f64
ã§ããåãæ瀺ããã«ã¯æ¥å°ŸèŸãã€ããŸãïŒ123u16
ã1.2f32
ãšãïŒã
æ°å€ãªãã©ã«ã¯_
ãæ¡åºåãã«äœ¿ãïŒç¡èŠããïŒã16é²æ°ã¯0x
ã8é²æ°ã¯0o
ã2é²æ°ã¯0b
ã®æ¥é èŸãã€ããŸãïŒ1_234
ã0xff
ã0o664
ã0b1010
ãšãïŒã
æµ®åå°æ°ãªãã©ã«ã¯e
ïŒ10ã®åªä¹ïŒè¡šèšãã§ããŸãïŒ1.23e2
==123
ïŒã
ãŸãããã€ã(u8)ãè¡šãb'A'
ããããŸãã
æŽæ°ã¯ãœãŒããã§ããŸãããæµ®åå°æ°ã¯NANããããããœãŒãã¯ã§ããŸããã
fn main() {
let mut x = vec![1, 4, 2, 3];
x.sort();
let mut y = vec![1.0, 4.0, 2.0, 3.0];
y.sort(); // ãã«ããšã©ãŒãNANãããã®ã§ãœãŒããçšæãããŠããªã
}
è«çå€å
Rustã§ã®è«çå€ã¯true
,false
ã§ãã
æåå
Rustã®æåã¯UTF-8ã§ãæå°åäœã¯char
ã§ããæååã¯str
åã§ãéåžžã¯&str
ã®åœ¢ã§äœ¿ãããŸãããŸããæšæºã©ã€ãã©ãªã§å®çŸ©ãããŠããString
ããã䜿ãããŸãã
ã¿ãã«å
ã¿ãã«ã¯è€æ°ã®å€ãã²ãšã€ã®è€ååã«ãŸãšããåã§ãã(ã)
ã§è¡šããŸãã
fn main() {
let tuple: (i32, f64, u8) = (500, 6.4, 1);
tuple.0; // 500
tuple.1; // 6.4
tuple.2; // 1
}
é åå
é
åã¯[ã]
ã§è¡šããŸãã
fn main() {
let arr: [i32; 5] = [ 0, 1, 2, 3, 4 ];
arr[0]; // 0ãªãªãžã³
let x = &arr[2..4]; // ã¹ã©ã€ã¹[2, 3]
let y = &arr[2..=4]; // ã¹ã©ã€ã¹[2, 3, 4] inclusive ranges
let z = &arr[2..]; // ã¹ã©ã€ã¹[2, 3, 4]
let u = &arr[..2]; // ã¹ã©ã€ã¹[0, 1]
}
é
åååãå°ãç¹æ®ã§ããµã€ãºæå®æãã¯[åå; èŠçŽ æ°]
ããµã€ãºæå®ãªãã ãš[åå]
ã§ãã
åæå
enum
ã§åæåãå®çŸ©ã§ããŸããC++ãšéã£ãŠãå€ãå€æ°ããã€ããšãã§ããŸããïŒç¢ºèªããŠãŸããããenumåã®ãµã€ãºã¯C++ã®union
ã®ããã«æ倧ã®å€ã«ãªããŸããïŒ
enum Msg {
Quit,
PrintH(String), // Stringåãæã€å€
ReportPoint(i32, i32), // ïŒã€ã®i32ãæã€å€
}
fn main() {
let x = Msg::Quit;
let y = Msg::PrintH("msg".to_string());
let z = Msg::ReportPoint(1, 2);
}
å¶åŸ¡æ§æã®èª¬æã§åãäžããŸãããããªããã¯ãã«ã§ããC++ã®nullptrã®ããã«æ±ããOption
ããšã©ãŒåŠçã«äœ¿ããResult
ãenumã§ãã
// ã€ã¡ãŒãžã§ãã
// enum Option {
// Some(ã),
// None,
// }
// ã€ã¡ãŒãžã§ãã
// enum Result {
// Ok(ã),
// Err(ã),
// }
fn main() {
let opt_x = Some(1);
if opt_x.is_some() {
println!("Some={}", opt_x.unwrap());
}
let opt_y = Option::<i32>::None;
if opt_y.is_none() {
println!("None")
}
let res_x: Result<i32, i32> = Ok(2);
if res_x.is_ok() {
println!("Ok={}", res_x.unwrap());
}
let res_y = Result::<i32, i32>::Err(3);
if res_y.is_err() {
println!("Err={}", res_y.err().unwrap());
}
}
//=>
// Some=1
// None
// Ok=2
// Err=3
æ§é äœ
struct
ã§ç¬èªã®åãå®çŸ©ã§ããŸããC++ãšéã£ãŠããã©ã«ããprivateã§ãclassã®ã¡ã³ããŒé¢æ°ã®ãããªæ©èœãã§ããŸãã
// æ§é äœå®çŸ©
struct My {
pub x: i32, // public
pub y: i32, // public
z: i32, // private
}
// ã¡ã³ããŒé¢æ°ã¯å¥ã§å®çŸ©
impl My {
// 決ãŸã£ãã³ã³ã¹ãã©ã¯ã¿ã¯ç¡ãããæ
£äŸãšããŠnewã䜿ããã
// selfåŒæ°ããªãã®ã§ã¯ã©ã¹é¢æ°
pub fn new(x: i32, y: i32) -> Self {
My { x: x, y: y, z: 1 }
}
// x, yãåãåã£ãŠã&mut Myãè¿ããã¡ã³ãé¢æ°ã«ãªãã
pub fn add(&mut self, x: i32, y: i32) -> &mut Self {
self.x += x;
self.y += y;
self
}
}
fn main() {
let mut x = My::new(1, 2); // ã¯ã©ã¹é¢æ°ã¯ã¯ã©ã¹å::é¢æ°å()ã§åŒã³åºã
x.add(3, 4).add(5, 6); // &Selfãè¿ãã¡ã³ãé¢æ°ã ãšé£ç¶åŒã³åºããã§ãã
}
traitïŒãã¬ã€ããç¹æ§ïŒ
C#ã§ãããšããã®interface
ãabstruct
ããRustã§ã¯trait
ãšãªããŸãã
// ãã¬ã€ã宣èš
trait Hoge {
fn hoge(&self);
// ããã©ã«ãå®è£
ãæžãã
fn fuga(&self) {
println!("Hoge");
}
}
// ç¶æ¿ïŒ
struct Foo {}
// ãã¬ã€ãå®è£
impl Hoge for Foo {
fn hoge(&self) {
println!("Foo");
}
}
// éåžžã®é¢é£é¢æ°ã¯å¥éãã€ãã©ããå®çŸ©ã§ãã
impl Foo {
fn add(&mut self, x: i32) {
}
}
// ç¶æ¿ïŒ
struct Bar {}
// ãã¬ã€ãå®è£
impl Hoge for Bar {
fn hoge(&self) {
println!("Bar");
}
fn fuga(&self) {
println!("Bar");
}
}
fn main() {
let x = Foo{};
let y = Bar{};
x.hoge(); //=> Foo
x.fuga(); //=> Hoge
y.hoge(); //=> Bar
y.fuga(); //=> Bar
}
ãã¬ã€ãå®è£
ã¯impl ãã¬ã€ãå for æ§é äœå
ããŒã¯ãŒãã䜿çšããŸããããã©ã«ãå®è£
ãããã°ãç¶æ¿å
ã§ã¯å®çŸ©äžèŠã§ãããå®çŸ©ããã°ãªãŒããŒã©ã€ããããŸãã
deriveïŒãã£ã©ã€ããå°ãåºãïŒ
Rustã«ã¯#[derive(ã)]
ãšãããC#ã®ã¢ããªãã¥ãŒãã®ãããªãã®ããããŸããïŒRustã«ãã¢ããªãã¥ãŒããããŸãïŒ
ããã¯ãã¯ãã®ïŒçš®ã§åå®çŸ©ããå¥ã®ã³ãŒããèªåçæããŠãããŸããããtraitã®æŽŸçãèªåå®è£
ãããšãã«äœ¿ãããŸãã
#[derive(Debug)] // èªåçæ察象ã®çŽåã«æžã
struct MyStruct {
foo: i32,
}
fn main() {
let s = MyStruct { foo: 1 };
println!("{:?}", s); // {:?}ã§Debug::fmt()ãåºåããã
}
âãããâãããïŒã€ã¡ãŒãžã§ãããã«ãã§ããŸãããïŒ
struct MyStruct {
foo: i32,
}
// `cargo install cargo-expand`åŸã«`cargo expand`ã§ãã¯ãã®å±éã確èªã§ãã
impl ::core::fmt::Debug for MyStruct {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(
f,
"MyStruct",
"foo",
&&self.foo,
)
}
}
fn main() {
let s = MyStruct { foo: 1 };
println!("{:?}", s);
}
#[derive(Debug)]
ã«ãããDebugãã¬ã€ãã®å®è£
ãèªåçæãããŸãã
ä»åmntime
ã§äœ¿ã£ããã®ãã¡ã
-
clap::Parser
: ã³ãã³ãã©ã€ã³åŒæ°ã®è§£æã©ã€ãã©ãªclapã®structå®çŸ©ããåŒæ°è§£æããã³ãŒããçæããã// Cargo.tomlãããã¥ã¡ã³ãã³ã¡ã³ãããã«ãã¡ãã»ãŒãžã«äœ¿çšããã #[derive(clap::Parser)] #[clap(author, version, about, long_about = None, setting = clap::builder::AppSettings::TrailingVarArg | clap::builder::AppSettings::DeriveDisplayOrder)] pub struct CliArgs { /// Perform NUM runs for each command. #[clap(short, long, value_parser, value_name = "NUM", default_value_t = 10)] pub runs: u16, /// Set the shell to use for executing benchmarked commands. /// /// This is executed as `sh -c time command1`. /// If execution confirmation is not obtained, also try `/usr/bin/env bash`. /// /// e.g.) sh, /opt/homebrew/bin/zsh #[clap(short = 'S', long, value_name = "COMMAND", default_value = "sh")] pub shell: String, /// Use shell built-in time. #[clap(long)] pub use_builtin: bool, /// The commands to benchmark. /// /// If multiple commands are specified, each is executed and compared. /// One command is specified with "--" delimiters (recommended) or quotation. /// However, in the case of command-only quotation marks, /// the subsequent ones are considered to be the arguments of the command. /// /// e.g.) mntime command1 --flag arg -- command2 -- 'command3 -f -- args' command4 -o "output files" #[clap(value_parser, required = true)] commands: Vec<String>, }
-
Clone
: Cloneãã¬ã€ããå®è£ ããclone()
ãclone_from()
ãã§ããããã«ãªãã -
Copy
: ããã©ã«ãã®ã ãŒãã»ãã³ãã£ã¯ã¹ã§ã¯ãªããã³ããŒã»ãã³ãã£ã¯ã¹ãšããŠæ±ãããæ瀺ãããå®è£ ããªãããŒã«ãŒãã¬ã€ãã§ããïŒi32ã&strãªã©åºæ¬çãªåã¯ã³ããŒã»ãã³ãã£ã¯ã¹ã§ããïŒ -
Debug
: Debugãã¬ã€ããå®è£ ãã{:?}
ã{:#?}
ã®ãã¬ãŒã¹ãã«ãã䜿ããããã«ãªãã#[derive(Debug)] struct MyStruct { foo: i32, } fn main() { let s = MyStruct { foo: 1 }; println!("{:?}", s); //=> // MyStruct { foo: 1 } println!("{:#?}", s); //=> // MyStruct { // foo: 1, // } }
ã¡ãªã¿ã«
{}
ã ãã®ãã¬ãŒã¹ãã«ãã¯std::fmt::Display
ãã¬ã€ããå®è£ ããŠãfmt()
ã䜿ããããã«ããŠããå¿ èŠãããã -
Default
: Defaultãã¬ã€ããå®è£ ããdefault()
ã䜿ããããã«ãªããenumã«ã€ããå Žåã¯ã#[default]
ã¢ããªãã¥ãŒãã§ããã©ã«ãå€ãæå®ããå¿ èŠããããŸãã#[derive(Default)] enum Kind { #[default] A, B, C }
-
Eq
: PartialEqãæ¯èŒé¢æ°ãå®è£ ããEqã¯ãã¹ãŠã®å€ã®çµã¿åãããPartialEqãæºããããšã瀺ãããŒã«ãŒãã¬ã€ãã§ããæµ®åå°æ°ã¯NAN
ãæ¯èŒã§ããªãã®ã§ãEq
ãã€ããŸããã -
Hash
: Hashãã¬ã€ããå®è£ ããhash()
ãhash_slice()
ã䜿ããããã«ãªããåãã£ãŒã«ãã®hashã®çµã¿åãããŠäœãããã -
PartialEq
: PartialEqãã¬ã€ããå®è£ ããeq()
ãne()
ãã§ããããã«ãªãã -
strum::AsRefStr
: enumãæ¡åŒµããŠããã䟿å©ãã¯ãéstrumã®ïŒæ©èœã§ãas_ref()
ã§æååãžå€æã§ããããã«ãªãã -
strum::EnumIter
: enumãæ¡åŒµããŠããã䟿å©ãã¯ãéstrumã®ïŒæ©èœã§ãiter()
ã§åæå€ãã€ãã¬ãŒã¿ãŒã§åããããã«ãªããuse strum::IntoEnumIterator as _; #[derive(strum::AsRefStr, strum::EnumIter)] enum Color { Red, Green { range: usize }, Blue(usize), Yellow, } fn main() { for color in Color::iter() { println!("{}", color.as_ref()); //=> // Red // Green // Blue // Yellow } }
-
thiserror::Error
: ãšã©ãŒã¡ãã»ãŒãžã®å®è£ ã楜ã«ããŠãããã©ã€ãã©ãªthiserrorã®å®çŸ©ã§ãã#[derive(thiserror::Error)] enum CmdError { #[error("Execution command is not finished yet. This is a bug in the source code.")] NotFinished, #[error("Could not parse the output of the `{0}` command. This is a source code issue, please provide the developer with the output of the `{0}` command.")] ParseError(&'static str), }
ãžã§ããªãã¯å
C++ã§ããtemplateïŒãã³ãã¬ãŒãïŒã¯Rustã§ã¯GenericïŒãžã§ããªãã¯ïŒã§ä»£çšããŸãã䌌ããããªåŠçãåãã«æ±ããŸãã
// Tããžã§ããªãã¯å
fn func<T>(a: T, b: T) -> T
where // Tã®æºããã¹ãæ¡ä»¶
T: std::ops::Add<Output=T> // Tã¯Addãã¬ã€ããå®è£
ãŠããŠãå ç®ãã§ãçµæã¯Tãšãªã
{
a + b
}
// whereãªãã§æžãããšãã§ããã
fn func2<T: std::ops::Add<Output=T>>(a: T, b: T) -> T {
a + b
}
fn main() {
let x = func(1, 2); // i32
let y = func(1.0, 2.0); // f64
let z = func2(1u32, 2u32); // u32
}
Boxå
Rustã¯åºæ¬çã«å€æ°ã¯ã¹ã¿ãã¯é åã«ä¿åãããŸããBox
ã䜿ããšå€æ°ãããŒãé åã«ä¿åãããŸãã
ã¹ã¿ãã¯ã¯ãã«ãæã«ãµã€ãºãæå®ãã¹ã¬ããããšã«æã£ãŠããŸããããã¿ãåçŽã ãã¡ã¢ãªã¢ãã¬ã¹ãéçŽããŠããã®ã§éãã§ããé¢æ°ã®ãã³ã«ããŒã¹äœçœ®ãäžäžãã䜿ãããããšã¹ã¿ãã¯ãªãŒããŒãããŒã«ãªã£ãŠã¡ã¢ãªç Žå£ãèµ·ããŠããŸããšãããžãã§ãã
ãŸããã¹ã¿ãã¯ã¯é¢æ°å
ã§ã®äœ¿çšéããã«ãæã«ããã£ãŠããå¿
èŠãããã®ã§ãåçãªåããã€ããšãã§ããŸããã
ããŒãã¯ããã°ã©ã å®è¡äžã«åçã«OSããã¡ã¢ãªãèŠæ±ããã®ã§ã倧ããªãµã€ãºãåé¡ãããŸããïŒãã¡ãã䜿çšéãå€ããããšç¢ºä¿å€±æããŠãšã©ãŒã«ãªããŸãïŒããã¡ãã¯ã¹ã¿ãã¯ã«æ¯ã¹ããšè€éã ãã¡ã¢ãªç©ºéãåºãã®ã§ãé
ããªã£ãŠããŸãããšã¯ããæè¿ã®CPUã¯ãã£ãã·ã¥ãå¹ãã®ã§ç¡è¶ãªäœ¿ãæ¹ããªããã°ååæ©ãã§ãã
Boxããžã§ããªãã¯ã®ã²ãšã€ã§ãã
struct MyLarge {} // ãµã€ãºã®å€§ããæ§é äœãšæã£ãŠãã ããã
impl MyLarge {
fn func(&self){
println!("MyLarge");
}
fn func_mut(&mut self) -> &mut Self {
println!("mut MyLarge");
self
}
}
fn main() {
let x = Box::<MyLarge>::new(MyLarge{}); // 倧ãããã®ã®ç¢ºä¿
let mut y = x; // ãã€ã³ã¿ãŒã®å·®ãæ¿ãã ããªã®ã§ã倧ãããã®ã§ãæ©ã
y.func(); // éåžžã®åãšåãããã«äœ¿ãã
y.func_mut();
let arr = ["a", "b", "c"];
puts(Box::new(arr));
}
// åŒæ°ã®é
åããã«ãæã«ãµã€ãºäžæã®ãããBoxã§å
ã
fn puts(arr: Box<[&str]>) {
for s in arr.iter() {
print!("{},", s);
}
}
Boxã䜿ããšããªã¢ãã£ãºã ãå®çŸã§ããŸãã
#[derive(Debug)]
struct MyPoint {
x: i32,
y: i32,
}
// åŠçãåãæ¿ããããããã«ããã¬ã€ãã宣èšãã
trait PrintTrait {
fn print(&self, p: MyPoint);
}
// åŠçïŒ
struct DbgPrint;
impl PrintTrait for DbgPrint {
fn print(&self, p: MyPoint) {
println!("{:?}", p); // ãããã°åºå
}
}
// åŠçïŒ
struct PrettyPrint;
impl PrintTrait for PrettyPrint {
fn print(&self, p: MyPoint) {
println!("{:#?}", p); // ãããã°ããªãã£åºå
}
}
// ãã¬ã€ãã¯ãã«ãæã«ãµã€ãºãããããªãã®ã§Box<ã>ã§å²ã
// 2015ãšãã£ã·ã§ã³ããã¯ãã¬ã€ãã®äœ¿çšãšåããããã«dynããŒã¯ãŒããå¿
èŠ
fn my_print(f: Box<dyn PrintTrait>, p: MyPoint) {
f.print(p); // ãã¬ã€ãã®é¢æ°åŒã³åºãããããšãåŒæ°ã§åãåã£ãå®è£
ã®åŠçãè¡ããã
}
fn main() {
let p = MyPoint{x:1,y:2};
// ãããå€ãããšåŠçãå€ããããã
let f: Box<dyn PrintTrait> = Box::new(DbgPrint);
//let f = Box::new(PrettyPrint); // ããã§ã¯æ£ããåæšè«ã§ããã®ã§çç¥å¯
my_print(f, p);
}
//=>
// MyPoint { x: 1, y: 2 }
åãšã€ãªã¢ã¹
Rustã§ã¯type ãšã€ãªã¢ã¹å = åå;
ãšãããšå¥åãä»ããããšãã§ããŸãã
type Point = (u32, u32);
fn func(x: Point) {
}
fn main() {
let p: Point = (1, 2); // ãšã€ãªã¢ã¹åã䜿ããããå®éã¯å
ã®å
func(p);
func((3, 4)); // åãšã€ãªã¢ã¹å
ã®ãçŽæ¥äœ¿ãã
}
void
C++ã§ããvoid
ã¯Rustã ãš()
ãšãªããŸããçŽããããã§ããOk(())
ã®ããã«ïŒéæ¬åŒ§ã®åœ¢ïŒOK()
åæåã«()
äœãå
¥ããªããè¡šãïŒã«ãªãããšããããŸãã
é¢æ°ã»ã¯ããŒãžã£ã»ãã¯ã
éåžžé¢æ°
ãããŸã§ã䜿ã£ãŠããfn
ããŒã¯ãŒãã§é¢æ°ãå®çŸ©ã§ããŸããRustã§ã¯C++ã®åŒæ°ã®åãå€ãããªãŒããŒããŒãã¯ã§ããŸããã
fn ret_string(x: i32) -> String {
return format!("{}", x); // è¿ãå€ã¯returnã§è¿ãã
}
// ãã«ããšã©ãŒãåŒæ°ã®åãéããªãŒããŒããŒãã¯ã§ããªã
fn ret_string(x: f64) -> String {
format!("{}", x) // æåŸã®è¡ã§ã»ãã³ãã³ããªããã°ããããè¿ãå€ãšãªã
}
ãã®å Žåã¯ãžã§ããªãã¯åã䜿ããŸãã
trait IntOrFloat{}
impl IntOrFloat for i32{}
impl IntOrFloat for f64{}
fn ret_string<T>(x: T) -> String
where
T: IntOrFloat + std::fmt::Display // +ã§è€æ°ã®æ¡ä»¶ãANDã§ããïŒORã¯ãªãããïŒïŒ
{
format!("{}", x)
}
fn main() {
let x = ret_string(1);
let y = ret_string(1.0);
let z = ret_string(1u32); // ãã«ããšã©ãŒãu32ã¯åãåããªã
}
ã¯ããŒãžã£
ç¡åé¢æ°ãšãã©ã ãåŒãšãåŒã°ãããã®ã¯Rustã ãšã¯ããŒãžã£ãšãªããŸãã|args|{exprs}
ã®æ§æã§ãã
fn exec
<F: FnOnce(i32, i32) -> i32> // ïŒååŒã³åºãi32ãïŒã€åãåããi32ãè¿ãã¯ããŒãžã£
(f: F) -> String // ãã®execé¢æ°èªäœã¯ã¯ããŒãžã£ãåãåããStringãè¿ãé¢æ°
{
let x = f(2, 3);
format!("{x}")
}
fn main() {
let x = "hoge".to_string();
let y =exec(|a, b| {
println!("in:{}={},{}", x, a, b);
a + b
});
println!("out:{}={}", x, y);
//=>
// in:hoge=2,3
// out:hoge=5
}
move || {}
ã«ãããšãã¯ããŒãžã£å
ã§ãã£ããã£ããå€æ°ã®æææš©ã移åããŸãã
fn main() {
let x = "hoge".to_string();
let y =exec(move |y| {
println!("{}={}", x, y);
y
});
println!("{}={}", x, y); // ãã«ããšã©ãŒãxãmoveãããŠãã
}
{ã}
ã®æ³¢æ¬åŒ§ã¯åŒïŒã€ãªãçç¥ãã§ããŸãã
fn main() {
let x = "hoge".to_string();
let y =exec(|y| y);
println!("{}={}", x, y);
}
FnOnce
ã®ãã¬ã€ãã¯ã»ãã«Fn
ãšFnMut
ãæšæºã§çšæãããŠããŸãã
fn exec_fn<F: Fn()>(f: F) {
f();
f();
}
fn exec_fn_mut<F: FnMut()>(mut f: F) {
f();
f();
}
fn exec_fn_once<F: FnOnce()>(f: F) {
f();
//f(); // ïŒåç®ã¯åŒã³åºããªã
}
fn main() {
let mut x = "hoge".to_string();
exec_fn(|| {
//x.insert(0, '#'); // mutableãã£ããã£ãŒã¯ã§ããªã
println!("{}", x)
});
exec_fn_mut(|| {
x.insert(0, '>');
println!("{}", x)
});
exec_fn_once(|| {
x.insert(0, '\t');
println!("{}", x)
});
//=>
// hoge
// hoge
// >hoge
// >>hoge
// >>hoge
}
-
Fn
: äœåºŠã§ãåŒã³åºããçŽç²é¢æ°ãmutableãã£ããã£ã¯ã§ããªããäžçªå¶éããã€ãã -
FnMut
: äœåºŠã§ãåŒã³åºããå¯äœçšã®ããé¢æ°ãmutableãã£ããã£ã§ãããæææš©ã®ç§»åã¯å¶éãããã -
FnOnce
: ïŒåºŠã ãåŒã³åºããå¯äœçšã®ããé¢æ°ãmutableãã£ããã£ã§ãããå¶éããããã
宣èšçãã¯ã
macro_rules!
ã§ãã¯ãã宣èšããŸããåŒã³åºãã¯!()
ã![]
ã!{}
ã®ã©ããã䜿ããŸããé¢æ°çãªã®ã¯!()
ãé
åçãªã®ã¯![]
ãæ§é çãªã®ã¯!{}
ããšããããšã§æ··ä¹±ãå°ãªãããŸãã
macro_rules! abs {
($x:expr) => {
if 0 <= $x {
$x
} else {
-$x
}
}
}
fn main() {
let x = abs!(-1);
let y = abs![2*2];
let z = abs!{-3*3};
println!("{},{},{}", x, y, z);
//=>
// 1,4,9
}
cargo expand
ã§èŠããšãã¯ãåŒã³åºãéšåã¯æ¬¡ã®ããã«ãªã£ãŠããŸãã
let x = if 0 <= -1 { -1 } else { --1 };
let y = if 0 <= 2 * 2 { 2 * 2 } else { -(2 * 2) };
let z = if 0 <= -3 * 3 { -3 * 3 } else { -(-3 * 3) };
C++ãšéã£ãŠããã¯ãã®åŒæ°ã¯æ§ææšã§ïŒå¡ãšããŠæ±ãããŸãããã®ãããååæŒç®ã§åªå é äœãå€ãã£ãŠãããããªããšããããšããããŸããã
以äžã¯åŒæ°ã§åŠçãåããããå¯å€åã®åŒæ°ãåãåãäŸã§ãã
macro_rules! max {
($x:ty) => { // åŒæ°ïŒã€ã ãã®ããŒãžã§ã³ïŒexpråŒã§ã¯ãªãtyåãåãåãïŒ
<$x>::MAX
};
($x:expr,$( $y:expr), *) => { // ïŒåç®ã®$yãïŒã€ä»¥äžã®åŒæ°
{
let mut max = $x;
$( // å¯å€åŒæ°ãã«ãŒãã§åã
max = if max < $y {
$y
} else {
max
};
)*
max
}
}
}
fn main() {
let x = max!(-1, 3, 0, 9, -9);
println!("{}", );
//=>
// 9
}
ãã¯ãã®åŒæ°ã¿ã€ãã¯expr
ãty
ã以å€ã«ãblock
ãident
ãªã©ãããããããŸãã
ã¡ãªã¿ã«assert!()
ãassert_eq!()
ã¯ãã¯ãã§ãããC++ãšéã£ãŠãªãªãŒã¹ãã«ãã§ãæå¹ã§ãããªãªãŒã¹ãã«ãã§ç¡å¹ã«ãªãdebug_assert!()
ã'debug_assert_eq!()
ãçšæãããŠããŸãããŸããdebugãšä»ããŠããã°ãªãªãŒã¹ãã«ãã§ç¡å¹ã«ãªãããã§ã¯ãªããDebug
ãã¬ã€ããdbg!()
ãªããããªãªãŒã¹ãã«ãã§ãæå¹ã§ãã
æç¶ãçãã¯ã
#[derive(ãã¯ãå)]
ãšã[ãã¯ãå]
ã§ä¿®é£Ÿããã®ããã¯ãã®ïŒçš®ã§æç¶ããã¯ããšåŒã°ããããã§ãã
èªåã§å®çŸ©ã§ããŸãããè€éãªã®ã§ããã§ã¯èª¬æçç¥ããŸããç§ãç解ããŠãªãã®ã§ãå¿
èŠã«ãªã£ãããŸãæ¬ãèªã¿çŽããŸãã
- å®è·µRustããã°ã©ãã³ã°å ¥é
å¶åŸ¡ãããŒ
åå²
Rustã®åå²ã«ã¯if
ãå©çšããŸããC++ãšéã£ãŠåŒãªã®ã§å€ãè¿ããã®ã§ïŒé
æŒç®åã«ã䜿çšããŸãã
fn main() {
let x = 1;
let y = if x == 0 {
100 // åŒãšããŠå€ãè¿ãå Žåã¯ãæåŸã®ã»ãã³ãã³ã¯ãªã
} else if x == 1 {
99 // ä»ã®åå²ãšåãåãè¿ã
} else {
100/x // ä»ã®åå²ãšåãåãè¿ã
};
}
ãŸããif let
ã§å€æ°ãæçžã§ããŸãã
// Option<T>ãã©ã
enum OptInt {
Some(i32),
None,
}
fn main() {
let x = OptInt::Some(1); // Option<T>ãªãSome(1)ã ãã§ãã
let y = OptInt::None;
let z = &x;
// Someã ã£ããvalã«å€ããã€ã³ããã
if let OptInt::Some(val) = z { // Option<T>ãªãSome(val)ã ãã§ãã
println!("{}", val); //=> 1
} else {
// Noneã®å Žå
}
}
ãã¿ãŒã³ãããã³ã°
C++ã§ãããšããã®switch
ã«ãããã®ããRustã§ã¯match
ã§ãã
enum Color {
Red,
Green { range: usize },
Blue(usize),
Yellow,
}
fn main() {
let x = Color::Blue(0);
x
match x {
Color::Red => {}
Color::Green{range:_} => {} // Greenã§å€ã¯ãªãã§ããã(`_`)
Color::Blue(0) => {println!("OK");} // Blueã§å€ã0ãªã
// Blueã§å€ã¯ãªãã§ããã(å
ã«åŠçããã0以å€)ãå€ã¯valã«ãã€ã³ãããã
Color::Blue(val) => {println!("{}", val);}
_ => {} // ãã®ä»ãC++ switchã®default:
}
}
match
ã¯ãã¹ãŠã®åå²ãã«ããŒããå¿
èŠããããŸããïŒæ¬åœãªãäžèšã³ãŒãã§ã¯_ =>
ã¯äœ¿ããªãæ¹ããenumèŠçŽ è¿œå æã®ãã¹ãæžãïŒ
if let
ã®ããã«ãã¿ãŒã³ãããããå Žåãå€ãå€æ°ã«ãã€ã³ãã§ããŸãã
ç¹°ãè¿ã
Rustã®ç¹°ãè¿ãã¯loop
ã䜿ããŸãã
fn hoge() -> bool {
return false;
}
fn fuga() -> bool {
return true;
}
fn main() {
loop {
if hoge() {
continue;
}
if fuga() {
break;
}
}
}
if
åæ§ã«loop
ãå€ãè¿ãããšãã§ããŸãããã®å Žåbreak val
ã®ããã«æžããŸãã
æ¡ä»¶ä»ãç¹°ãè¿ã
while
æ¡ä»¶ã€ãã«ãŒãããããŸãã
fn main() {
while(true) {
break;
}
}
ã€ãã¬ãŒã¿ã«ãŒã
C#ã§ããforeachããRustã§ã¯for
ã«ãªããŸãã
fn main() {
let x = vec![1, 2, 3];
'l1: for i in x {
while(true) {
if (i == 0) {
break 'l1;
}
}
}
}
loop
ãwhile
ãfor
ãšãã«ã©ãã«ãä»ãããïŒäžèšäŸã ãš'l1:
ïŒãbreakã§ã©ãã«ãæå®ãããšäžæ°ã«å€åŽã®ã«ãŒããæããããŸãã
ã³ã¬ã¯ã·ã§ã³æäœ
å¶åŸ¡ãããŒãšã¯éããŸãããã€ãã¬ãŒã¿ã«ãŒãã®ä»£ããã«iter()
ã§ã€ãã¬ãŒã¿ã«ããŠåçš®æäœé¢æ°ã䜿ããŸãã
fn main() {
let x = vec![9, 1, 8, 2];
// æå°å€ååŸ
println!("{}", x.iter().min().unwrap()); //=> 1
// å ç®åèšååŸ
println!("{}", x.iter().sum::<i32>()); //=> 20
// 5æªæºã®ãªã¹ãã«å€æ
println!("{:?}", x.iter().filter(|&x| *x < 5)
.collect::<Vec<_>>()); //=> [1, 2]
// ç³ã¿èŸŒã¿ã§ä¹ç®åèšååŸ
println!("{}", x.iter().fold(1, |s, x| s * x)); //=> 144
// ãã§ãŒã³åŒã³åºããã§ããŸãã
println!("{}", (1..) // ç¡éãªã¹ããã
.filter(|x| 1 == x % 2) // å¥æ°ã ãã«çµã£ãŠ
.nth(3) // ãªãã»ãã3ïŒïŒåç®ïŒãåãåºã
.unwrap()); //=> 7
}
ã€ãã¬ãŒã¿ã®åãåºãæ¹ã§äœ¿ãé¢æ°ãéã£ãŠããŸãã
-
iter()
:&T
ãšãªã¹ãå ã®å€ã«å¯Ÿããåç §ãšããŠã€ãã¬ãŒã¿ãåãã -
iter_mut()
: '&mut T'ãšãªã¹ãå ã®å€ã«å¯Ÿããmutableãªåç §ãšããŠã€ãã¬ãŒã¿ãåãã -
into_iter()
:T
ãããã¯mut T
ãšmoved valueãšããŠã€ãã¬ãŒã¿ãåããå ã®ãªã¹ãã¯æææš©ããªããªãã®ã§ã以éã§ã¯äœ¿ããªããªããŸãã
ãšã©ãŒåŠç
Result
Rustã«ã¯äŸå€åŠçããªãã®ã§ãšã©ãŒã¯æ»ãå€ã§è¡šããŸãããã®ããã®åResult<T, E>
åãçšæãããŠããŠãOk(_)
ã§æ£åžžå€ããErr(_)
ã§ãšã©ãŒæ
å ±ãååŸã§ããŸãã?
ã䜿ããšãOk(_)
ãªãç¶ç¶ãErr(_)
ãªãreturn Err(_)
ãççž®ããŠãããŸãã
ã¡ãªã¿ã«Option<_>
ã«?
ã䜿ããšãSome(_)
ãªãç¶ç¶ãNone
ãªãreturn None
ãççž®ããŠãããŸãã
fn div(x: i32) -> Result<i32, &'static str> {
if x != 0 {
Ok(100 / x)
} else {
Err("zero divide!")
}
}
fn hoge(x: i32) -> Result<i32, &'static str> {
let y = div(x)?;
// ?ã¯äžèšã®ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒ
// let y = match div(x) {
// Ok(t) => t,
// Err(e) => return Err(e),
// };
println!("OK");
Ok(y)
}
fn main() {
let x = div(5); // Result<>å
let y = x.unwrap(); // Result<>ããOkã®i32ãåãåºãããã ãErrãªããããã¯ãçºç
}
ãããã¯
ãšã©ãŒãåŠçããã«ãã®å Žã§ã¹ã¬ãããçµäºãããpanic!()
ããããŸããResultãOptionã§æ£åžžå€ãå
¥ã£ãŠããã®ãåãã£ãŠããã°ãunwap()
ã䜿ããŸããããç°åžžå€ãå
¥ã£ãŠããã°panic!()
ã§ãããã¯ãçºçããŸãã
fn div(x: i32) -> Result<i32, &'static str> {
if x == 0 {
Err("zero divide!")
} else {
Ok(100 / x)
}
}
fn main() {
let x = div(5); // Result<>å
let y = x.unwrap(); // Result<>ããOkã®i32ãåãåºãããã ãErrãªãpanic!()ãçºç
}
ãããã¯ã§ãåŠçãç¶ç¶ãããå Žåã¯ãcatch_unwind()
ã䜿ããšãResult<Ret, E>åã«ã©ããããŠãããŸãããã ããããã¯çºçæã®åºåã¯ãããã®ã§ãšã©ãŒåŠçã«ã¯äœ¿ããŸãããCã©ã€ãã©ãªåŒã³åºãã®FFIå¢çãè¶
ããå Žåã«å®å
šã®ãã䜿ãæãã®ããã§ãã
fn main() {
// çµæãResult<Ret, E>åã«ã©ããããŠè¿ã
let x = std::panic::catch_unwind(|| {
assert!(false);
});
if let Err(payload) = x { // ãããã¯ãçºçããã°ãErr(_)ã«ãããã¯æ
å ±ãå
¥ã£ãŠã
eprintln!("panicked");
std::panic::resume_unwind(payload); // ãããã¯ãåçºè¡
}
}
éåžžã¯ãããã¯æã«å·»ãæ»ããçºçããDrop
ãã¬ã€ããåŒã°ãããªã©ã®åŸå§æ«ããŸãããã ãããããã¯äžã®drop()
äžã§ãããã¯ãçºçãããªã©ã®ïŒéãããã¯ã¯å³æ匷å¶çµäºããããããã«ããªãã·ã§ã³ã§panic="abort"
ãæå®ããããšãããã¯ãã³ãã©ã ãå®è¡ãããŸããabortã¢ãŒãã«ãããšãå·»ãæ»ãã®ããã®äœåãªãªãŒããŒãããããªããªãã®ã§çµèŸŒã¿ãªã©æ¥µéãŸã§åããããšãã«äœ¿ãããã§ãã
ãã®ãããã¯ãã³ãã©ã¯set_hook
ã§çœ®ãæããããšãå¯èœã§ãã
fn initialize_cli() {
// æ¢åã®ãããã¯ãã³ãã©ãååŸ
let default_panic_hook = std::panic::take_hook();
// ãããã¯ãã³ãã©ãäžæžã
std::panic::set_hook(Box::new(move |panic_info| {
finalize_cli();
// ä¿åãããããã¯ãã³ãã©ãåŒã³åºã
default_panic_hook(panic_info);
}));
}
å®è£ è£å©çšã®ãã¯ãã§ãããã¯ãæå³çã«çºçããããã®ããããŸãã
-
todo!
: æçµçã«ã¯å®è£ ããããä»ã¯ãŸã æªå¯Ÿå¿ã®ãšãã«äœ¿çšããã -
unimplemented!
: å®è£ ããäºå®ããªãïŒåŒã°ããããšãæ³å®ããŠããªãïŒãšãã«äœ¿çšããã -
unreachable!
: åŠçãå°éããªããšãïŒåå²æŒãææã®å¯Ÿå¿æïŒãªã©ã«äœ¿çšããã
ãšã©ãŒåŠçã楜ã«ãªãã©ã€ãã©ãª
ãšã©ãŒåŠçã楜ã«æžããããã«ããå€éšã¯ã¬ãŒãããããŸããAnyhowãšthiserrorã§ããã©ã¡ããåãæ¹ãäœãããŠããŠãçµã¿åãããŠäœ¿çšå¯èœã§ãã
use anyhow::Context as _;
// thiserrorã§ããšã©ãŒã¡ãã»ãŒãžãç°¡åã«å®çŸ©ã§ãã
#[derive(thiserror::Error, Debug)]
enum MyErr {
#[error("This is test error")]
Test,
}
// anyhowã§Resultã®æå®ã楜ã«ãªãã
fn hoge(x: i32) -> anyhow::Result<Vec<u8>> {
if x == 0 {
Err(MyErr::Test.into())
} else {
let path = format!("path/{}.txt", x);
let content = std::fs::read(path.as_str())
// anyhowã®contextã§ãšã©ãŒã¡ãã»ãŒãžã«ä»å æ
å ±ãäžãããã
.with_context(|| format!("Failed to read str from {}", path))?;
Ok(content)
}
}
fn main() -> anyhow::Result<()> {
hoge(0)?;
//=>
// Error: This is test error
hoge(1)?;
//=>
// Error: Failed to read str from path/1.txt
// Caused by:
// No such file or directory (os error 2)
Ok(())
}
ãã«ãã¹ã¬ãã
Rustã«ã¯ãã«ãã¹ã¬ããã«å¿
èŠãªæ©èœãçšæãããŠããŸããæšæºã§ã¯æäœéã®ãã®ã ãã§ãããå€éšã¯ã¬ãŒãã䜿ãã°ãã䟿å©ã«ãªã£ããããããã§ãã
ããã§ã¯åçŽãªã¹ã¬ããã«ã€ããŠèª¬æããŸã(説æããŸããããRustã«ã¯async
ãawait
ããããŸã)ã
Cell
Cellã¯å€æŽå¯èœã¡ã¢ãªé
眮ã§ãC++ã§ããmutable
宣èšã®ããã«immutableãªæ§é äœã®äžã§ãå€æŽå¯èœãªãã£ãŒã«ããäœããŸãã
struct SomeStruct {
regular_field: u8,
special_field: std::cell::Cell<u8>,
}
fn main() {
let my_struct = SomeStruct {
regular_field: 1,
special_field: std::cell::Cell::new(1),
};
let new_value = 2;
// my_struct.regular_field = new_value; // immutableãªã®ã§ãšã©ãŒ
my_struct.special_field.set(new_value); // immutableãªã®ã«ãå€æŽå¯
assert_eq!(my_struct.special_field.get(), new_value);
}
Cellãä¿æããåã«ãã£ãŠäœ¿ããã¡ãœãããå€ãããŸãã
-
get()
ã¯Copyãã¬ã€ããå¿ èŠã§ããå€ãã³ããŒããŠè¿ããŸãã -
take()
ã¯Defaultãã¬ã€ããå¿ èŠã§ããå€ãdefault()ãšå ¥ãæ¿ããå ã®å€ãè¿ããŸãã
RefCell
RefCellã¯ä¿æããå€ãžã®åç §ãåããCellã®äžäœçã§ãã
struct SomeStruct {
cell: std::cell::Cell<u8>,
refcell: std::cell::RefCell<u8>,
}
fn square(x: &mut u8) {
return *x *= *x;
}
fn main() {
let my_struct = SomeStruct {
cell: std::cell::Cell::new(3),
refcell: std::cell::RefCell::new(3),
};
square(&mut my_struct.refcell.borrow_mut());
assert_eq!(*my_struct.refcell.borrow(), 9);
// åç
§ãæ段ããªããã³ããŒã«ãªãããã ããlet mutãããŠãããšãget_mut()ã§åç
§ãåãã
square(&mut my_struct.cell.get());
//assert_eq!(my_struct.cell.get(), 9); // å®è¡ãšã©ãŒ
}
Cell
ãšRefCell
ãå¥ããŠããã®ã¯ãåçšãã§ãã«ãŒã圱é¿ããŠããŸããRefCell
ã¯åçãªåçšãã§ãã«ãŒãšãªãããã«ãæã§ã¯ãªãå®è¡æã«åçšãã§ãã¯ãèµ°ããŸãããã®ããããªãŒããŒããããååšããã®ã§ãéåžžã¯Cellãããã§ãããã
// Cellå©çšçã¯ãã«ããšã©ãŒãåºã
fn main() {
let mut x = std::cell::Cell::new(1);
let y = x.get_mut(); // ããã§ïŒåç®ã®å€æŽå¯èœãªåçšããŠãã
x.set(2); // ããã§ïŒåç®ã®å€æŽå¯èœãªåçšã«ãªããã«ããšã©ãŒ
println!("{},{}", x.get(), *y);
}
// RefCellå©çšçã¯ãã«ããéãããããå®è¡æã«ãããã¯ãçºçããã
fn main() {
let x = std::cell::RefCell::new(1);
let y = x.borrow_mut(); // ããã§ïŒåç®ã®å€æŽå¯èœãªåçšããŠãã
*x.borrow_mut() = 2; // ããã§ïŒåç®ã®å€æŽå¯èœãªåçšã«ãªãããã«ããšã©ãŒã¯çºçããªã
println!("{},{}", *x.borrow(), *y);
}
/*=>
thread 'main' panicked at 'already borrowed: BorrowMutError', src/main.rs:5:8
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
*/
Rc/Arc
Rustã®Rc
ãšArc
ã¯åç
§ã«ãŠã³ã¿ãŒæ¹åŒã§å€ãä¿æããŸããéãã¯ãArc
ã®ã«ãŠã³ã¿ãŒæäœãã¹ã¬ããã»ãŒãã«ãªã£ãŠããç¹ã§ããArc
ã¯Atomically Reference Counterã®ç¥ã§ãã
fn main() {
let a: std::rc::Weak<i32>;
let b: std::rc::Rc<i32>;
let x: std::rc::Weak<i32>;
{
let c = std::rc::Rc::new(1); // ã«ãŠã³ã¿ãŒ = 1
a = std::rc::Rc::downgrade(&c); // Weakã¯ã«ãŠã³ã¿ãŒæäœããªã
if let Some(d) = a.upgrade() {
println!("a={d}");
}
b = c.clone(); // ã«ãŠã³ã¿ãŒã¢ãã = 2
// cãç Žæ£ãããã«ãŠã³ã¿ãŒããŠã³ = 1
}
{
let y = std::rc::Rc::new(2); // ã«ãŠã³ã¿ãŒ = 1
x = std::rc::Rc::downgrade(&y);
if let Some(z) = x.upgrade() {
println!("x={z}");
}
// yãç Žæ£ãããã«ãŠã³ã¿ãŒããŠã³ = 0
}
if let Some(d) = a.upgrade() { // ã«ãŠã³ã¿ãŒã1ãªã®ã§true
println!("a={d}");
}
if let Some(z) = x.upgrade() { // ã«ãŠã³ã¿ãŒã0ãªã®ã§false
println!("{z}");
}
}
/*=>
a=1
x=2
a=1
*/
Atomic
Arc
ãAtomicallyãšããã®ã¯ãã«ãŠã³ã¿ãŒæäœããã®Atomic
åãå©çšããŠããããã§ããéåžžã®åã ãšãå€æäœãè€æ°ã®CPUåœä»€ã«ãªãããšãããããã«ãã¹ã¬ããæã«æåãäºæž¬äžå¯èœã«ãªãããšããããŸããããã¯ãããã°å®å
šã§ããããããŸã§ã¯å¿
èŠãªãå°ããªæäœãïŒã€ã®CPUåœä»€ïŒæäœäžã«ã»ãããå²ã蟌ãŸããªãïŒã§è¡ãã®ãã¢ãããã¯ãªæäœã§ãã
fn main() {
let mut x = std::sync::atomic::AtomicI32::new(1);
// ã¹ã¬ãã競åæã®é çªä¿èšŒã®æ¹åŒïŒãã¡ããšèŠããŠãŸãããå¿
èŠã«ãªã£ãã調ã¹ãŠãïŒ
let order = std::sync::atomic::Ordering::Relaxed;
assert_eq!(x.load(order), 1);
x.store(2, order);
assert_eq!(*x.get_mut(), 2);
x.compare_exchange(2, 3, order, order); // ä»ã®å€ã2ã ã£ããã3ã代å
¥ãã
assert_eq!(*x.get_mut(), 3);
x.fetch_add(1, order); // increment
assert_eq!(*x.get_mut(), 4);
}
æšæºã§çšæãããŠããåã¯å ¬åŒããã¥ã¡ã³ãã«æžãããŠããŸãã
thread_local
Rustã®ã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžã¯thread_local!
ãã¯ãã§å®çŸ©å¯èœã§ãã
fn main() {
thread_local! {
// Cellã¯ãŸã unstableãªãããªã®ã§ãRefCellã䜿çš
pub static FOO: std::cell::RefCell<i32> = std::cell::RefCell::new(1);
static BAR: std::cell::RefCell<i32> = std::cell::RefCell::new(2);
}
FOO.with(|x| {
assert_eq!(*x.borrow(), 1);
});
BAR.with(|x|{
*x.borrow_mut() = 3;
assert_eq!(*x.borrow(), 3);
});
}
å®éã®åã¯LocalKey<ã>
ãšãªããŸãã
thread
Rustã§ã®ã¹ã¬ããçæã¯std::thread::spawn()
ã§è¡ããŸãã
use std::borrow::Borrow;
fn func() {
thread_local! {
static BAR: std::cell::RefCell<i32> = std::cell::RefCell::new(2);
}
BAR.with(|x|{
println!("{}", *x.borrow());
*x.borrow_mut() += 1;
println!("{}", *x.borrow());
});
}
fn main() {
let t1 = std::thread::spawn(|| {
func();
});
let t2 = std::thread::spawn(||{
func();
});
t1.join();
t2.join();
}
//=>
// 2
// 3
// 2
// 3
ã¹ã¬ããã®ã¹ã³ãŒãã¯éåžžãããã°ã©ã çµäºãŸã§ã«ãªã£ãŠããŸããŸãããã®ããåçšãã§ãã«ãŒã§ãã«ããšã©ãŒã«ãªãããšããããŸãããã®å Žåã¯thread::scope()
ã§ã¹ã¬ããã®ã¹ã³ãŒããæ瀺ããŸãã
fn main() {
let mut a = vec![1, 2, 3];
let mut x = 0;
std::thread::scope(|s| {
s.spawn(|| {
println!("hello from the first scoped thread");
// We can borrow `a` here.
dbg!(&a);
});
s.spawn(|| {
println!("hello from the second scoped thread");
// We can even mutably borrow `x` here,
// because no other threads are using it.
x += a[0] + a[2];
});
println!("hello from the main thread");
});
// After the scope, we can modify and access our variables again:
a.push(4);
assert_eq!(x, a.len());
}
Mutex
Rustã§ããã¯ãæ±ãã«ã¯Mutex
ã䜿ããŸããéåžžArc<Mutex<>>
ã®åœ¢ã§äœ¿ããåã¹ã¬ããã§ä¿æã§ããããã«ããŸãã
use std::borrow::{BorrowMut as _, Borrow as _};
fn main() {
use std::sync::Arc;
let data = Arc::new(std::sync::Mutex::new("".to_string()));
let mut handles = Vec::<std::thread::JoinHandle<()>>::new();
for i in 0..6 {
let data = Arc::clone(&data); // Arcã®æ©èœã§åç
§ã«ãŠã³ã¿ãŒãå¢ãããŠã¯ããŒã³
handles.push(
std::thread::spawn(move || { // ã ãŒãã¯ããŒãžã£
let mut lock = data.lock().unwrap(); // ããã¯ååŸãMutexGuard<>å
lock.borrow_mut().push((b'a' + i) as char)
})
)
}
for h in handles {
h.join().unwrap();
}
println!("{}", data.lock().unwrap().borrow()); //=> abcdefãšãabcefdãšã
}
ããã¯äžã«ãããã¯ãçºçãããšãPoisoningïŒäžæ¯ïŒç¶æ ã«ãªããŸãã
channels
Rustã«ã¯ã¹ã¬ããéã§ããŒã¿ã®ãããšãã«äœ¿ãããã£ã³ãã«ã®æ©èœããããŸããæšæºã§ã¯å€éä¿¡->ååä¿¡ã®Multi-Producer, Single-Consumerã ããããŸãã
ãã£ã³ãã«ã¯FIFOã§ããããã¡ã«è²¯ããããŸãããã®ãããå
ã«éä¿¡ããŠãæ£ããåä¿¡ã§ããŸãã
fn main() {
let mut data = "".to_string();
let (tx, rx) = std::sync::mpsc::channel(); // éä¿¡çšãšåä¿¡çšã®å¯Ÿã«ãªããã£ã³ãã«
let mut handles = Vec::<std::thread::JoinHandle<()>>::new();
for i in 0..6 {
let tx = tx.clone(); // éä¿¡çšãã£ã³ãã«ãè€è£œ
handles.push(
std::thread::spawn(move || { // ã ãŒãã¯ããŒãžã£
tx.send((b'a' + i) as char); // éä¿¡
})
)
}
let timeout = std::time::Duration::from_millis(100);
loop {
match rx.recv_timeout(timeout) { // åä¿¡
Ok(ch) => {
data.push(ch);
}
Err(std::sync::mpsc::RecvTimeoutError::Timeout) => { // ã¿ã€ã ã¢ãŠãæ
handles.retain(|h| { // æªçµäºã¹ã¬ããã ãæ®ãïŒçµäºãããã®ã¯åé€ïŒ
!h.is_finished()
});
if handles.is_empty() {
break; // å
šã¹ã¬ããçµäº
}
}
Err(_) => {
panic!("ERROR");
}
}
}
println!("{}", data); //=> abcdefãšãabcefdãšã
}
ãã£ã³ãã«ã¯éä¿¡åŽããã¹ãŠéãããããšãåä¿¡ããšã©ãŒã«ãªããŸãããããå©çšããŠãã¹ã¬ããã®çµäºã®å€å®ãã·ã³ãã«ã«ã§ããŸãã
fn main() {
let mut data = "".to_string();
let (tx, rx) = std::sync::mpsc::channel();
for i in 0..6 {
let tx = tx.clone();
std::thread::spawn(move || {
tx.send((b'a' + i) as char);
// ã¹ã¬ããçµäºæã«éä¿¡ãã£ã³ãã«ãïŒã€éãããã
});
}
drop(tx); // ãªãªãžãã«ã®éä¿¡ãã£ã³ãã«ãéãããã
while let Ok(ch) = rx.recv() { // ãã¹ãŠã®éä¿¡ãã£ã³ãã«ãéãããããErrã«ãªã
data.push(ch);
}
println!("{}", data); //=> abcdefãšãabcefdãšã
}
Send / Sync
ãã«ãã¹ã¬ããã«é¢ä¿ããSend
/Sync
ããŒã«ãŒãã¬ã€ããšãããã®ããããŸãããããã¯ã³ã³ãã€ã©ãèªåã§æ±ºå®ããŠä»äžããŠãããŸãã
Send
ããããã®ã ããã¹ã¬ãããè¶
ããŠè»¢éã§ããSync
ããããã®ã ããã¹ã¬ããéã§åç
§ã®å
±æãã§ããŸãã
use rand::distributions::uniform::SampleBorrow;
fn main() {
let rc = std::rc::Rc::new(1);
let arc = std::sync::Arc::new(2);
for i in 0..6 {
let rc = rc.clone();
let arc = arc.clone();
std::thread::spawn(move || {
println!("{}", *rc); // ãã«ããšã©ãŒã
println!("{}", arc.borrow());
});
}
}
ãã®ã»ãã®åšèŸºæ©èœ
Doc comments
C++ã®Doxygenã®ãããªããã¥ã¡ã³ãã³ã¡ã³ããRustã§ã¯æšæºã§çšæãããŠããŸãããããcrates.ioãžå ¬éãããšãèªåçæãããããã¥ã¡ã³ããã¡ã€ã«ãdocs.rsã§èŠãããšãã§ããŸãã
//! ãã®ãã¡ã€ã«ã®æŠèŠ
//!
//! ãã®ãã¡ã€ã«ã®è©³çŽ°ãªèª¬æ
//! ïŒè¡ä»¥äžæžãããšãã§ããŸãã
/// æ§é äœã®æŠèŠ
///
/// æ§é äœã®è©³çŽ°ãªèª¬æ
///
/// **Wow** Markdownèšæ³ã䜿ããïŒæ¹è¡ã¯å
¥ããããã空è¡ã®æ®µèœåãã䜿ãïŒ
struct My {
/// ãã£ãŒã«ãã®æŠèŠ
///
/// ãã£ãŒã«ãã®è©³çŽ°ãªèª¬æ
x: i32,
}
/// é¢æ°ã®æŠèŠ
///
/// # Examples:
/// ```
/// # use std::io; // # å§ãŸãã¯ããã¥ã¡ã³ãã«åºåãããªããããã¹ãæã®ã¿æå¹
/// assert!(1, 2)
/// ```
/// ã³ãŒãäŸãæžããŸãã
/// lib.rsãããã°ãã©ã€ãã©ãªãã«ãåŸã«ãã¹ãããã
fn func() {
}
//!
ã§ã€ã³ããŒã©ã€ã³ããã¥ã¡ã³ãïŒå
è¡ã¯ãŒãã®èšèŒïŒãéå§ã///
ã§ã¢ãŠã¿ãŒã©ã€ã³ããã¥ã¡ã³ãïŒåŸç¶ã¯ãŒãã®èª¬æïŒãéå§ããŸããè€æ°è¡ã³ã¡ã³ãããŒãžã§ã³ããã/*! ã */
ã§ã€ã³ããŒãããã¯ããã¥ã¡ã³ãã/** ã */
ã§ã¢ãŠã¿ãŒãããã¯ããã¥ã¡ã³ããšãªããŸããããèŠãã®ã¯ããã¡ã€ã«ã®ããã¥ã¡ã³ãã³ã¡ã³ãã¯//!
ã§å§ããŸãããã以å€ã®ããã¥ã¡ã³ãã³ã¡ã³ãã¯///
ã§å§ããŸãã
ããã¥ã¡ã³ãã³ã¡ã³ãã«ã¯ããŒã¯ããŠã³èšæ³ãã€ããããšãã§ããã³ãŒããããã¯ã§ãã¹ãã³ãŒããæžããŸãããã®èšäºæžããšãã«æ°ä»ããã®ã§ãããããã¥ã¡ã³ãã³ã¡ã³ãäžã®ãã¹ãã¯ã©ã€ãã©ãªã¿ãŒã²ããã®ã¿æå¹ã§ããã€ããªã¿ãŒã²ããã®å Žålib.rs
ãã¡ã€ã«ãçšæããŠã©ã€ãã©ãªãšããŠããã«ãã§ããããã«ããªããšãããªãããã§ããïŒãã®èšäºæžããŠããã£ããïŒ
main.rs
ãšlib.rs
ãäž¡æ¹äœ¿ãå Žåãæ··åããªãããã«Cargo.toml
ã®[lib]
ã»ã¯ã·ã§ã³ã§ååãå€ããã®ãããã§ãããã
cargo doc
ã§target/doc
ãã©ã«ãã«ããã¥ã¡ã³ããã¡ã€ã«ãçæãããŸããcargo doc --open
ãšãããšãçæãããã¡ã€ã«ããã©ãŠã¶ã§éããŠãããŸãïŒæå
ã®Safariã§ã¯æ£ãã衚瀺ã§ããªãã®ã§ãChromeã§éãçŽããŠãŸãïŒã
ã¡ãªã¿ã«Rustã®è€æ°è¡ã³ã¡ã³ãã¯ãã¹ããå¯èœã§ãã
/* è€æ°è¡ã³ã¡ã³ã
/* å
¥ãåã³ã¡ã³ãéå§ C++ãªãããã§ã³ã¡ã³ããçµäºããŠããŸã */
ãããRustã¯ãã¹ãã§ããã®ã§ããã®è¡ãã³ã¡ã³ãã§ãã
*/
fn main()
test
Rustã«ã¯ãã¹ãç°å¢ãæšæºã§çšæãããŠããŸãã
/** Calc double number
# Examples:
```
# use test_rs::*; // ãã¹ãã¯ã©ã€ãã©ãªãšå¥ã«ãã«ããããã®ã§ããã«ãã¹æå®ãå¿
èŠ
let x = hoge(1);
assert_eq!(2, x);
let x = hoge(9);
assert_eq!(18, x);
```
*/
pub fn hoge(x: i32) -> i32 {
x * 2
}
#[cfg(test)] // testãã«ãæã®ã¿æå¹ã«ãªã
mod test {
use super::*; // æ
£äŸ
#[test] // ããããããšãã¹ã察象ã«ãªã
fn hoge_zero() {
assert_eq!(0, hoge(0));
}
#[test]
fn hoge_negative() {
assert_eq!(-2, hoge(-1));
assert_eq!(-18, hoge(-9));
}
}
ãŸãã¯ããã¥ã¡ã³ããŒã·ã§ã³ãã¹ãã«ã€ããŠã§ããããã¥ã¡ã³ããŒã·ã§ã³ã³ã¡ã³ãäžã®ã³ãŒããããã¯ã¯ãã¹ã察象ãšãªããŸãïŒãã ãã©ã€ãã©ãªã¿ãŒã²ããã®ã¿ã§ãã€ããªã¿ãŒã²ããã¯ãã¹ããããªãïŒãããã¯ã©ã€ãã©ãªããã«ãããŠãããã«äŸåããäžæçãªãã€ããªããã«ãããå®è¡ãããŸããåã³ãŒããããã¯ãå¥ã
ã«fn main() { ã³ãŒãããã㯠}
ãšã¡ã€ã³é¢æ°ã§å²ãããã³ãŒããšããŠå®è¡ãããŸãã
ãã®ããããã¹ãã§ããã®ã¯pub
ã®ã€ããå
¬éããããã®ã ãã§ãåŒã³åºãã«ã¯ã©ã€ãã©ãªã®ã¯ã¬ãŒãåããã®ãã¹ã§æžãå¿
èŠããããŸãã#
å§ãŸãã¯ããã¥ã¡ã³ãã«èŒããªãã®ã§ããã«ãã§ã¯å¿
èŠã ãæ
å ±ãšããŠã¯äžèŠãªè¡ã«äœ¿ããšãã£ããããããã¥ã¡ã³ãã«ãªããŸãã
ã³ãŒããããã¯ã®èšèªæå®ãRust以å€ïŒããšãã° ```txt
ãšãïŒã«ããå Žåã¯ãã¹ã察象å€ã«ãªããŸããç¡èŠããã®ãè¡šã ```ignore
ã¢ããªãã¥ãŒãããããŸããã¢ããªãã¥ãŒã㯠```hould_panic
ã§ãã¹ãäžãããã¯ãçºçããããã§ãã¯ã ```no_run
ã§ãã«ãã®ã¿ã§ãã¹ãã¯ããªãããªã©ã»ãã«ããããŸãã
詳现ã¯Documentation testsãåç
§ãã ããã
次ã«ãŠããããã¹ãã«ã€ããŠã§ãã#[test]
泚éãfn
ã®åã«ã€ãããšãã®é¢æ°ã¯ãã¹ãé¢æ°ãšããŠäœ¿çšãããŸãããã¡ãã®å Žåã¯åããã¡ã€ã«ïŒã¢ãžã¥ãŒã«ïŒãªã®ã§ãã©ã€ããŒããªãã®ããã¹ãå¯èœã§ããéåžžã¯åã¢ãžã¥ãŒã«ãšããŠmod test{ ã }
ã§å²ã¿ãããã«#[cfg(test)]
泚éãã€ããŠãã¹ãæã®ã¿æå¹åããŸãããŸããtestã¢ãžã¥ãŒã«äžã¯åŒã³åºããã¹ãçç¥ããããuse super::*;
ããã䜿ãããŸãã
æåŸã«çµ±åãã¹ãã«ã€ããŠã§ããsrc
ãã©ã«ããšåãéå±€ã§tests
ãã©ã«ããçšæãããã®äžã«.rsãã¡ã€ã«ã眮ããšãããããããã¹ããã€ããªãšããŠãã«ããããŸãããã®äžã§#[test]
泚éãããfn
ããã¹ãé¢æ°ãšããŠå®è¡ãããŸãããã¡ãã¯ããã¥ã¡ã³ããŒã·ã§ã³ãã¹ããšåãããå¥ãã€ããªãšããŠãã«ããããã®ã§å
¬éã®ãã®ãããã¹ãã§ããŸããã
fmt/lint
cargo fmt
ã§ãœãŒã¹ã³ãŒããèªåãã©ãŒããããããŸãã
cargo clippy
ã§ãªã³ã¿ãŒãèµ°ããŸããcargo clippy --fix
ãšãããšä¿®æ£ã§ãããã®ã¯èªåã§ä¿®æ£ãããŸãã
ãŸãšã
Rustã¯æææš©ïŒã©ã€ãã¿ã€ã ãåçšå«ãïŒãç解ã§ããã°ããµã¯ãµã¯ãããŠããã©ãŒãã³ã¹ãããã§ãããããã£ãšã
ãããŸã§ã¯ã³ã³ãã€ã©ãšå
±éããŠã圌ãã®ã¡ãã»ãŒãžãåãåã£ãŠã¬ãã«ã¢ããããŠãããŸããããC++ãšæ¯ã¹ããæ Œæ®µã«åããããã話ããããŠãããŠãŸããã
ãããŠãã°ã®å°ãªãå®å
šãªããã°ã©ã ãäœã£ãŠãããããäžçã«ãªãã®ãé¡ã£ãŠãŸãã
ããããããããã€ãŒãããããããžãèŽããããã³ã¡ã³ãã倧æè¿ã§ãïŒ
Discussion