7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixirのチートシートを作ろう #9 制御構造その1

Last updated at Posted at 2024-12-14

1. OverView

さて、制御構造です。ifだ、分かりやすい奴…
いやぁ、whileもforもなくて、どーなるかと思ってた。

それでも、今まで、さんざんEnumで以下みたいな処理と同等の関数を見てきましたね。

for( TGT in list ){
    if(list[TGT] == "なんたら"){ printf("かんたら\n")}
}

これで、ifとか要らん気になりそうですが。コツコツとやっていきましょう。

あ、本日、短いです。理由は明日知ると思いますが…

2. まずは解説

2.1 ifとunless

見慣れているifだけに一言。

https://elixirschool.com/ja/lessons/basics/control_structures#if-%E3%81%A8-unless-0
「Elixirでは偽とみなされる値は nil と真理値の false だけだということに、留意すべきです」

これ、if( value )とかコード書いちゃうオレは注意な。
さて、ifはif~do~else~endで書くみたいですな。

if String.valid?("Hello") do
  "Valid string!"
else
  "Invalid string."
end
"Valid string!"

String.valid?("Hello")がtrueであれば、"Valid string!"を表示します。そうでなければ、"Invalid string."を。

if "a string value" do
  "Truthy"
end
"Truthy"

ちょっと面白いのが、これ、値を返してるだけなんですね。
実際のコーディングでは、こう言う使い方多そう。

2.2 unless

unlessは、「条件が否定される時だけ作用します」

unless is_integer("hello") do
  "Not an Int"
end

まー、ここでも、「Elixirでは偽とみなされる値は nil と真理値の false だけだということに、留意すべきです」ですね。

2.3 case

さて、Elixir Schoolを見てみましょう。

複数のパターンに対してマッチする必要があるなら、 case/2 を使うことができます…

さて、ではやってみよう。

case {:ok, "Hello World"} do
  {:ok, result} -> result
  {:error} -> "Uh oh!"
  _ -> "Catch all"
end
"Hello World"

…素晴らしい。さて、今回のキモ

「変数は case/2 命令文の中に含まれる重要な要素です。これが無いと、マッチするものが見あたらない場合にエラーが発生します:」

case :even do
  :odd -> "Odd"
end
** (CaseClauseError) no case clause matching: :even
    (stdlib 6.0) erl_eval.erl:1272: :erl_eval.case_clauses/8
    #cell:a6cn227ei3bph5zz:1: (file)

…じゃぁ、なんにでもマッチするパターンを追加しましょうか。

iex(8)> case :even do
...(8)>   :odd -> "Odd"
...(8)>   _ -> "Not Odd"
...(8)> end
"Not Odd"

_ を追加することで、すべてのパターンにマッチする様になりました。

さて、最後に
「case/2 はパターンマッチに依存しているため、パターンマッチと同じルールや制限が全て適用されます。
 既存の変数に対してマッチさせようという場合にはピン ^ 演算子を使わなくてはいけません」

…これ、caseのマッチ対象側にも、変数使えるんですね。

iex(9)> pie = 3.14
3.14
iex(10)> case "cherry pie" do
...(10)>   ^pie -> "Not so tasty" ー>こっちにはマッチしてない。
...(10)>   pie -> "I bet #{pie} is tasty" <-この時点では、パターンマッチなので、pieには"cherry pie"が入る。
...(10)> end
"I bet cherry pie is tasty"
iex(13)> pie
3.14 <-この時点では、上のcase内部のcherryは捨てられ、元のpieが評価されている。

これ、caseが終わると、変数pieが、3.14に戻ってますね。
変数のScopeが原因だとは思いますが、これは後で解説する必要がありそうです。

すいませんが、サンプルにあるGuard句は、別途説明させてください。
本日はここらへんで

3. # 3. 本日のチートシート!

制御構造の名 説明
if 条件がtrueの時、do 以下の行を実行する if String.valid?("Hello") do
"Valid string!"
else
"Invalid string."
end
"Valid string!"
unless 条件がnilかfalseの時、do 以下の行の行を実行する unless is_integer("hello") do
"Not an Int"
end
case do以降の行のパターンマッチを行い、->以降の行を実行する。 case {:ok, "Hello World"} do
{:ok, result} -> result
{:error} -> "Uh oh!"
_ -> "Catch all"
end
"Hello World"

4. 本日の課題.…

僕の宿題をまとめておきます。

4.1 Expressions allowed in guard clausesを読もう

「この例は公式のElixirのGetting Startedガイドから直接持ってきています。
 公式ドキュメントからExpressions allowed in guard clausesを読んでみてください」

…guard構文らしいですね。
こんな話もあるので、後で調べて記事にしておきます。
https://qiita.com/FL4TLiN3/items/110d177175d6708322ca#%E3%81%82%E3%81%A8%E3%81%8C%E3%81%8D

4.2 変数のスコープと説明しよう

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?