Go言語 ~基礎編~ 条件とループ

go

学習記録

今回は、条件とループについて学んでいきたいと思います。

Goの例外処理

Go言語には、try-catch構文がありません。Go言語はシンプルさを追求した言語のため、実装していないようです。

では、エラーをキャッチしたい場合はどうすればいいのでしょうか?

Go言語の関数は、戻り値を複数返すことができる特徴を持っています。この特徴を利用して、エラー発生時にErrorオブジェクトを返すように実装している関数があります。

例えば、Go言語の組み込み関数ある「ReadString」メソッドを見て見ましょう。

ご覧の通り、戻り値に”string”と”error”が設定されています。

つまり、この関数を利用するには、戻り値とエラーの両方を受け取る変数が必要です。

例を挙げてみましょう。

errと変数宣言している箇所が、errorオブジェクトを受け取る変数です。err変数の例外処理の記述方法は、Go言語統一で以下のように書きます。

エラーの場合は、errorオブジェクトを返します。

エラー以外の場合は、nilを返却することになっていますので、err変数の値がnilかどうかをチェックします。

エラー処理をしたくない場合は、「_(アンダースコア)」で受け取ることもできます。

Go言語では、宣言した変数がソースコードの中で一度も使用されていないとコンパイルエラーになります。しかし、「_」については例外で、コンパイルエラーを回避することができます。

ただし、エラーを無視するメリットは「ない」と思いますので、nilの判定チェックにて、エラーハンドリングした方が無難だと思います。

また、エラー処理にlogパッケージの「Fatal」関数を利用しています。この関数は、「メッセージを出力する」機能と「プログラムの実行を止める」機能を提供します。

条件判定

Go言語は、「if文」にて条件判定を行います。

or条件の場合は、「||」, and条件の場合は「&&」キーワードを指定できます。この辺りは他の言語と同じですね。

やってみよう1

プログラミングを学ぶ上で、アウトプットが大切です。学んだ知識をここで確かめてみましょう。

<問題>
ファイルを読み込んで、ファイルサイズを出力するプログラムを作成してください。
<制限事項>
・ファイル情報の取得は、osパッケージのStat関数を使うこと
・err 処理を入れること

こちらが、解答例です。

型変換(Strings->Numbers)

前回、float64とint型のタイプの型変換を学びました。その復習になりますが、以下の通りに実装すれば、型変換が行えましたね。

しかし、stirngsをnumbers型に変換するのは少し大変です。

単純にint型の値をstringで囲ってみましょう。

何が出力されるでしょうか?答えは「空白」が出力されます。

int -> string の場合はどうなるでしょうか。

今度は、コンパイルエラーが発生しましたね。Strings をNumbers型に型変換するには、strconvパッケージを利用します。

やってみよう2

以下のコードをstrconvパッケージ関数を使って書き換えて下さい。

解答例です。

parseFloatを使った方が、コードが綺麗に見えますね。

変数のスコープ

変数のスコープ(有効範囲 )について、少し触れておきましょう。

以下のソースコードを見てください。

このソースコードを実行するとどうなるでしょうか?

答えは、「コンパイルエラー」になります。

Println関数でstatusの出力を試みましたが、エラーになってしまいました。何が起こったのでしょうか?

Go言語では、ブロックごとに変数の有効範囲が決められています。ブロックとは、中括弧({})で囲まれた部分を指します。

上記の例では、if-else内でそれぞれstatusを初期化しているので、各々のブロック内でしか有効になりません。

ブロックは、ネストすることも可能で、内から外に向けて有効範囲が広がっていきます。

やってみよう3

先ほどのコードの修正をしてみましょう。解答例を書いておきます。

Short Variable Declarationの宣言

Short Variable Declarationを覚えているでしょうか?「:=」を使った変数宣言の方法の一つでしたよね。

この方法で宣言された変数が同じスコープ内に存在する場合は、二度目の初期化はできません。

では、問題ですが、以下の場合はどうなると思いますか? err 変数に対して、short variale declarationを使いました。

実は、これについてはコンパイルエラーになりません。

一つでも新しい変数名が一緒に宣言された場合は、short variable declarationを使うことができるのです。

Go関数は複数の変数を返却できる言語ですので、一つ一つの変数に対して新しく名前をつける(再利用できない)方法は、コーディングする上で大変になるからですね。

また、もう一つ「関数外からの宣言ができない」という特徴があります。

これが、varキーワードを使った変数宣言との最大の違いになります。

ループ

プログラミングの定番であるループ処理について学びましょう。

まずは、サンプルコードを見てください。

ループは常に「for」キーワードから始まります。

・x := 0
=> 変数の初期化です。ループの繰り返し回数によく利用されます。
・x < 6
=> ループ条件です。この条件が「True」の間だけループします
・x++
=> ループが一回りする度に必ず実行されます。初期化変数に対してカウントを繰り上げる役割を与えられることが多いです(ループ終了条件に移行させる)

先ほど示したforループの型が「最も一般的」な型となりますが、次のような宣言も可能です。

continueとbreak

ループ処理に必須な「continue」と「break」について学びましょう。

この二つのキーワードは、ループ処理をコントロールすることができます。

キーワード意味
continueループ処理のイテレーションをループブロック内のコードを実行せずにスキップする
breakループ処理を抜ける

言葉ではわかりずらいと思いますので、サンプルコードを見てみましょう。

continueの場合

まずは、continueです。下記のサンプルコードを実行するとどうなるでしょうか?

答えは、「START」が3回出力されるだけになります。

「fmt.Println(“END”)」処理がスキップされて次のイテレーションに処理が移行したことがわかると思います。

breakの場合

breakの場合は、どうなるでしょうか?

答えは、「START」が1回のみ出力されます。

breakキーワードは、ループ処理自体を抜けるので、1回しか出力されません。

現場では、continueとbreakキーワードはよく使用します。そして、このキーワードはバグを生みやすい部分なので、よく理解しておいて下さい。

まとめ

今回学んだことを最後にまとめて終わりにしたいと思います。

・Goの例外処理
 -> Go言語には、try-catch構文はない
 -> Go言語は、複数の戻り値を返却できる
 -> nilチェックによりエラー判定を行う
  if err != nil { log.Fatal(err) }
 -> エラーを無視したい場合は、「_(アンダースコア)」を使用する
・Goの条件判定
 -> if構文を用いる
・ Strings->Numbersへの型変換
 -> strconvパッケージを利用して型変換を行う
・変数のスコープ
 -> ファイル、パッケージ、if, for それぞれにスコープが存在する
・Short Variable Declaration(:=)
 -> 同一スコープ内で、二度目の初期化はできない。ただし、複数の変数を一緒に宣言し、かつ、片方が一度目の初期化の場合は、可能。
 -> 関数外からの初期化はできない
・ループ
 -> for構文を用いる
 -> 制御構文に、continueとbreakがある

参考書籍

次回

次回は、Go言語の関数について学びましょう。

コメントを残す