「Rust」の版間の差分
削除された内容 追加された内容
→制御構造: rustfmt タグ: 2017年版ソースエディター |
タグ: 2017年版ソースエディター |
||
383 行
=== 分岐 ===
Rust は、[[#if|if]] と [[#match|match]] の2つの分岐構文を持ちます。
==== if ====
ifは、条件式に基づき分岐し、分岐先の式を評価します。
ifの値は、分岐先の式の値です。
elseを省略し条件式が偽であった場合のifの値は <code>()</code> です。
;構文:<syntaxhighlight lang=ebnf>
if-expr := if 条件式 '{' 式1 '}' [ else '{' 式2 ] '}'
</syntaxhighlight>
:;[https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=84117443c135c52137b9005717322e82 条件式に整数を使うと]:<syntaxhighlight lang=Rust line>
fn main() {
let
if i {
}
}
</syntaxhighlight>
:;
error[E0308]: mismatched types
--> src/main.rs:4:8
|
4 | if i {
| ^ expected `bool`, found integer
For more information about this error, try `rustc --explain E0308`.
</syntaxhighlight>
:: Rustでは、ifに限らず、条件式は、bool 型でなければいけません。
;[https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c8960df447a87aaeaecced963d20cde if.rs]:<syntaxhighlight lang=rust line>
fn main() {
let
println!("
} else {
println!("
}
let s = if i == 0 {
"ゼロ"
} else {
"非ゼロ"
};
println!("
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
零
ゼロ
</syntaxhighlight>
:気をつけたいのは、式の値が参照されるifでは、それぞれの式(ここでは <code>"ゼロ"</code> と <code>"非ゼロ"</code>)にセミコロン<code> ; </code>を付けてはいけない点です。
:: もし セミコロン<code> ; </code> をつけると、ブロックの値は、Unit 型 <code>()</code> になります。
:: ifの、分岐先の2つの式の型は同じでなければいけません。
:: else節が省略された場合は、Unit 型を返さなければいけません。
::: 式の最後に、セミコロン<code>};</code> が必要ということです<ref>C言語系では、式を文にする為いに<code>};</code> が必要です。Rustもそう説明されている場合がありますが、Rustでは式の型の一致が目的です。<ref>。
:また、<syntaxhighlight lang=rust inline>let s = if i == 0 {</syntaxhighlight>の文末の<code>};</code> のセミコロンも忘れがちです。
:Rust では if に限らず、コードブロックは式の一種で値を返します<ref>コードブロックが値を持つプログラミング言語としては、BCPLや[[Ruby]]があります。</ref>。その場合、コードブロックの最後の式がコードブロックの値となりセミコロン<code> ; </code>は不要で、もし、<code> ; </code>をつけると<code> ; </code>の次の式(=空文)の値<code> () </code>がコードブロックの値になります。
この特徴は、関数型プログラミングを意識したものですが、同時に後に説明する所有権の移譲で重要な役割を果たします。
453 ⟶ 449行目:
Rustでは、C言語のNULLに相当する値は None です。
通常の変数は None の代入は受付けませんが、Some() を使うと None を取り得る変数が宣言できます<ref>[https://doc.rust-lang.org/stable/std/option/enum.Option.html Option in std::option - Rust]<</ref>。
;[https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=afb9193c50a316090b6e3119f994f8cf some.rs]:<syntaxhighlight lang=rust line>
fn main() {
let mut x = Some(0);
512 ⟶ 508行目:
==== match ====
matchは、パターンに基づき分岐し、分岐先の式を評価します。
matchの値は、分岐先の式の値です。
matchは、C言語でいうswitch case 文と似ていますが、switch文は式とリテラルの値の一致を上から順に検査しますが、matchでは式がパターンに適合するかを上から順に検査します。
また、whenはbreakが必要ありません(フォールスルーしません)。
;構文:<syntaxhighlight lang=
match-expr := match 式 '{'
パターン1 '=>' 式1 ,
パターン2 '=>' 式2 ,
:
パターンn '=>' 式n ,
変数 '=>' どのパターンにもマッチしなかった場合の式 ,
'}'
</syntaxhighlight>
: パターンと式を '=>' で繋いだものをアームといいます。
: パターンが変数だとあらゆる値にマッチし、式の値が束縛されます。典型的には、<code>_</code> アンダースコアで、これは値を束縛しないワイルドカードパターンです。
: パターンは網羅する必要があるので、最後のアームのパターンをワイルドカードを置く事が多いですが、例えば bool 型の値ならば flase と true の2つのパターンで網羅できるのでワイルドカードをパターンとするアームは不要です(コンパイル時に warning になります)。
下記コードは、[https://doc.rust-jp.rs/rust-by-example-ja/flow_control/match.html Rust 日本語ドキュメント] のサンプルコードをもとに、英語や課題などの情報を除いたものです。
;[https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=36834ebbee0d26d6b2374469cf98664e コード例]:<syntaxhighlight lang=rust line>
fn main() {
let number = 13;
531 ⟶ 543行目:
13..=19 => println!("A teen"),
// その他の場合
_ => println!("Ain't special"),
}
let boolean = true;
// マッチは式でもある。
let binary = match boolean {
false => 0,
true => 1,
// _ => 2, // !!! note: `#[warn(unreachable_patterns)]` on by default !!!
};
println!("{} -> {}", boolean, binary);
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text
Tell me about 13
A teen
true -> 1
</syntaxhighlight>
=== 反復 ===
|