読み込み中...
この講座では、プログラミングが全く初めての方でも安心してGoの基本を学べるように、一緒に手を動かしながら進めていきます。 まずは、Goの基本的な「書き方」から学んでいきましょう。
まずは、Goの基本的な書き方をみていきましょう。前回お試しで作成したmain.goをみてみると、
package main
import "fmt"
func main() {
fmt.Println("Hello World!");
}これを実行すると「Hello, world!」と文字が表示されます。ポイントとしては、
mainパッケージだけは特別で、実行可能なプログラムであることを示しています。fmt.Println を使う場合は必ず必要になります。""(ダブルクォーテーション)で囲まれた部分は文字列と呼ばれ、文字の並びとして扱われます。Javaと処理の流れは似ていて、mainパッケージ内部のmain関数を起点に処理が実行されます。そのため、main関数外に書いた処理は実行しても自動で処理されないことに注意してください。
package main
import "fmt"
func main() {
fmt.Println("Hello World!");
}
// ↓実行しても処理されない(「こんにちは」は出力されない)
〜〜〜 いろんな処理 〜〜〜
fmt.Println("こんにちは");
}※以降、Goのコード例はmain関数内のみ書きます。パッケージ名などは省略しています。
また、コメントアウトでメモを残すこともできます。
プログラムにメモや説明を書きたいときは、// や /* ... */ を使ってコメントを書くことができます。//以降の文字はプログラムとして実行されません。
fmt.Println("Hello, world!")
// これはコメントです。プログラムには影響しません。
fmt.Println("Goを学ぼう!") // このようにコードの横に書くこともできます
/*
これは複数行にわたるコメントです。
プログラムには影響しません。
*/また、goを実行をするには
go run 対象ファイルのコマンドを打つと実行できます。 ※他の実行方法もありますが、今回はこの方法で実行してください。
プログラミングの超基礎的な概念である変数。変数は、数値や文字などの値を入れられる領域でわかりやすくいうとデータを入れる箱です。 また、変数を使う時によく出てくる言葉もあるのでそれも覚えておきましょう。
Goでは変数は以下のように宣言、初期化、代入します。
// 変数の宣言
var name string
// 変数の宣言と初期化
var message string = "はじめまして!"
fmt.Println(message)
// 変数への代入
name = "田中 太郎"
message = "こんばんわ!!!"
fmt.Println(name)※Goでは「未使用の変数が存在する」とエラーになり、実行できません。この時、AAA declared and not used というようなエラー文が出るのでその場合は一度コードを見て、使ってない変数がないかどうか確認してみてください。
Goでは、「田中 太郎」といった文字列を扱う際はダブルクォーテーション " で囲う必要があります。
また、Javaのような String name と似た宣言の仕方です。Goでは変数名の後にstringなどのデータ型を記述する必要があります。ただし、Goには短縮宣言という便利な機能があります。
// 短縮宣言
message := "はじめまして!"
name := "田中 太郎"
fmt.Println(message)
fmt.Println(name)これはvar message string = "はじめまして!"と書くのと同じ意味です。:=を使うと、Goが自動的にデータ型を判断してくれます。かなり便利なので覚えておきましょう。
Goで扱えるデータの主な種類は、以下の通りです。
JSやJavaではデータがないものをNullとなっていましたが、GoではNullではなくnilとなります。
※厳密にはNullとnilは若干違いますが、最初は「データがない」というイメージだけでOKです。
また、JSで扱った配列はGoだと
に該当します。Goでは、スライスをよく使います。スライスは角括弧[] を使って定義します。
Goのスライスは スライス名 []データ型 で宣言することができます。同時にデータも設定する場合は スライス名 []データ型 = []データ型{データ1, データ2, データ3}と書きます。短縮宣言は スライス名 := []データ型{データ1, データ2, データ3} のように書きます。データ側の型は省略できないことに注意です。
さらに、リストの個々のデータにアクセスするには、インデックスというものを使います。インデックスはいわば「場所」のようなもので「先頭から何番目か」を表す番号です。注意点として一番先頭は 0 から始まります。
// int型のスライスを作成
var numbers []int
// スライスに要素を追加
numbers = append(numbers, 5)
numbers = append(numbers, 2)
fmt.Println(numbers) // [5 2]と表示
// スライスの要素を更新
numbers[1] = 4
fmt.Println(numbers) // [5 4]と表示
// 最初から全ての要素を入れておくことも可能
fruits := []string{"apple", "banana", "cherry"}
fmt.Println(fruits) // [apple banana cherry]と表示
fmt.Println(fruits[1]) // "banana"と表示スライスのデータ操作のポイントとして、
超基礎的な概念である演算子。算数的な計算で使う演算子(+や-とか)や、二つのデータを比較するのに使う比較演算子、「AかつB」のような数学の「集合、命題」の時に使った論理演算子をプログラミングでもよく使います。それぞれみていきましょう。
算数的な計算で使う演算子(算術演算子)は以下のように使います。
a := 5
b := 10
fmt.Println(a + b) // 15
fmt.Println(a - b) // -5
fmt.Println(a * b) // 50
fmt.Println(b / a) // 2
a += 3 // a = a + 3 と同じ意味
fmt.Println(a) // 8
a-- // a = a - 1 と同じ意味
fmt.Println(a) // 7基本的な四則演算で使います。使い方は算数とほぼ同じです。他にも乗数や余りの計算もできますが今回は割愛します。
また、変数への代入の場合はa = a + 3をa += 3のように省略して書くことができます。さらにその代入で加える(+)もしくは引く(-)値が1の場合はそれぞれ、a++,a--のように省略することができます。こちらよく使うので覚えておきましょう。
比較演算子は、2つの値を比較して論理値(trueまたはfalse)を出す時に使います。
x := 5
y := 1
z := "5"
fmt.Println(x == y) // false(値が等しくない)
fmt.Println(x > y) // true(xはyより大きい)
fmt.Println(y <= x) // true(yはx以下)
// Goでは異なる型同士の比較はコンパイルエラーとなるため実行できません
fmt.Println(x == z) // コンパイルエラーそれぞれ解説します。まず==は、2つの値が等しいか型も含めて比較します。二つの値が等しいときはtrueになり、等しくないときはfalseになります。
二つの値を比較する>では、左側が右より大きければtrueになり、それ以外はfalseとなります。<を使った場合はその逆です。
似たようなもので>=は、左側が右以上(右の値を含む)ならtrue、それ以外はfalseとなります。<=を使った場合はその逆です。
例えば、x < 5の場合は「xは5より小さい(5未満)か」なのでfalseとなりますが、x <= 5は「xは5以下か」なのでtrueとなります。
また、Goでは型が異なるもの同士の比較を行なった場合、コンパイルエラー(コード→機械語の変換でのエラー)になるため実行できないことに注意してください。
論理演算子は、論理値を操作するために使います。
tr := true
fl := false
fmt.Println(tr && fl) // false(AND)
fmt.Println(tr || fl) // true(OR)
fmt.Println(!tr) // false(NOT)それぞれ解説します。AND条件にしたい(両方trueでないとtrueにならない)場合は&&を使います。これによりAND条件の判定をすることができます。
OR条件にしたい(どちらかがtrueならtrueになる)場合は||を使います。NOT条件(論理値の逆転)をしたい場合は、その論理値の前に!を置きます。似たようなもので比較演算子で「xとyが等しくないとき」としたいときは、x != yとします。1個目の=を!にすることで、比較した結果の否定値になります。
JSの時とほぼ同じイメージでOKです。
また、今回は変数のみで論理演算子を使いましたが、実際は比較したものに対して論理演算子を使用します。具体的に、AND条件でいうと
fmt.Println(3 <= x && x < 10)このように「xが3以上かつ10未満か?」という複合した比較をする際に使用します。細かい使い方は次の制御構文の章で解説します。 これらの使い道としては、算術演算子は数値などのデータの四則演算に、比較演算子と論理演算子は変数などの中身によって処理を変えるために使います。
超基礎的な概念、制御構文を解説します。制御構文は、プログラムの実行内容を制御するための構文です。Goでは、条件分岐(if文、switch文)とループ(for文)があります。※JSやJavaでのWhileはGoでは使えません
if文は、条件に基づいて異なるコードを実行するために使います。先ほどの変数xを使って、
x := 5
if 3 <= x && x < 10 {
fmt.Println("3以上、10未満です")
} else if 5 < x {
fmt.Println("5より大きいです")
} else {
fmt.Println("それ以外")
}if文は大きく三つのブロックに分かれています。
if 条件 { ... }: 条件を満たす場合のみ、波括弧{ }内の処理を実行します。else if 条件2 { ... }: 前の条件を満たさなかったが、条件2を満たす場合のみ、処理を実行します。else { ... }: 全ての条件を満たさなかった際に実行されます。内容としては下の図のように、
・xが3以上、10未満なら、「3以上、10未満です」と出力する(水色)
・それ以外で5より大きい場合(実質的には10以上)なら、「5より大きいです」と出力する(濃い赤)
・それ以外なら「それ以外」と出力する(黄緑)
今回は「3以上、10未満です」が表示されますね。
試しに、先ほどの x を違う値にして(違う値を代入)して色々試してみてください。
もっと複雑に書いてみると、
x := 10
if 3 <= x && x < 10 {
if x == 3 {
fmt.Println("xは3です")
} else if x == 4 {
fmt.Println("xは4です")
} else if x != 6 {
fmt.Println("xは6じゃないです")
}
} else if 5 < x {
fmt.Println("5より大きいです")
} else {
fmt.Println("それ以外")
}このようにして、条件に合わせた処理を的確に実行することができます。
switch文は、いろいろな条件をピッタリ合うものと比較し、一致した時だけ特定の操作をすることができます。これにより、多くの「もし〜の場合」といった複雑な条件分岐を簡単に書けるようになります。よく使うのは「たくさんの選択肢の中から選ぶ」時の処理とかで役立ちます。 switch文は以下のような仕組みになっています。
x := 5
switch x {
case 20:
fmt.Println("20です")
case 5:
fmt.Println("5です")
default:
fmt.Println("それ以外")
}このように「特定の対象」に対して合致したパターンでの処理のみを行うことができます。switch文の仕組みは以下の通りです。
switch 対象: 比較したい対象を指定します。case パターン: パターンを指定します。一致した場合、そのブロックの処理を実行します。Goのswitchは、一致したcase以降の処理は自動的に終了するため、JSの時のbreakは不要です。default: どのcaseにもマッチしなかった場合の処理を指定します。for文は、一定の回数だけループさせる時に使います。何回も繰り返し処理を実行したりする時に使います。例えば、「1~3の数字を出力して」は以下のように書くことができます。
fmt.Println(1)
fmt.Println(2)
fmt.Println(3)では、「1~100の数字を出力して」だとちょっと面倒ですね。素直にfmt.Println(1);からfmt.Println(100);を書けばできますが大変です。そんな時に使うのがこの繰り返し(ループ)であるfor文です。for文でやった例は以下です。
for i := 1; i <= 100; i++ {
fmt.Println(i)
}たった3行で1~100の数字を出力できます。どうなっているか解説すると「変数iが100以下ならfmt.Println(i)して、その後にiを1増やす」ということを繰り返しています。もっと詳しくすると、for文の構造は、
for 変数を定義・初期化※for文内のみ使える変数; 繰り返しを継続するかの判定; 処理が終わった後の更新 {
処理
}となっていて今回の場合は、
iを定義(初期化)i <= 100がtrueなら処理実行{ ~処理~ }の処理を実行i = i + 1の省略形i++: iに1を加算といったことをしています。このようにして繰り返し処理をしていきます。 また、Goではwhileは使えないがforを使って再現することができる。
i := 1
for i <= 100 {
fmt.Println(i)
i++
}このようにforの後に条件式だけを書くことで、その条件がtrueの間、処理を繰り返します。
さらに無限ループを書くこともできます。条件式を省略することで、無限にループする処理を実装できます。
for {
// 永遠に実行される処理
if ループを抜ける条件 {
break
}
}無限ループは、breakキーワードを使って意図的にループを終了させることができます。
ですが永遠に終了しないループは極力使わないようにしましょう。繰り返し文を書く際はちゃんと終わることを確認しながらやることが大事です。
※無限ループを起こした場合、停止ボタンもしくは実行中のターミナル/コマンドプロンプト上でショートカットの Ctrl+C を押すと止まります。
関数(ファンクション) は、特定の処理をひとまとめにして名前をつけ、必要なときに何度でも呼び出して使うことができるものです。
・関数を使うメリット
Goの関数の書き方は以下の通りです。
※これ以降、全体のコードを表示します。
※mainメソッド外に関数(hello)を書いているので注意してください。
package main
import "fmt"
// 関数の宣言(メソッドの定義)
func hello() {
fmt.Println("こんにちは!")
}
func main() {
// 関数の呼び出し
hello() // 「こんにちは!」と表示される
hello() // もう一度呼び出すと、また「こんにちは!」と表示される
}func: 関数を定義するためのキーワードです。hello: これが関数の名前です。(): 関数の名前の後に続く丸括弧です。ここに引数(ひきすう) と呼ばれるデータを入れることがあります。なくてもOKです。{}: 波括弧の中に、関数が実行する処理(処理ブロック)を書きます。もちろん複数行書くことも可能です。関数には、外部からデータを受け取ったり、処理結果を返したりする機能もあります。
returnというキーワードを使います。package main
import "fmt"
// 引数を受け取る関数
func greetByName(name string) {
fmt.Println("こんにちは、" + name + "さん!")
}
// 引数を受け取り、戻り値を返す関数
func add(a, b int) int {
culc := a + b
culc = culc - 1
return culc // 最終計算結果を返す
}
func main() {
greetByName("太郎") // 「こんにちは、太郎さん!」と表示
greetByName("花子") // 「こんにちは、花子さん!」と表示
result := add(5, 3) // add関数に5と3を渡し、処理終わったデータ(戻り値)をresult変数に入れる
fmt.Println(result) // 「7」と表示
anotherResult := add(10, 20)
fmt.Println(anotherResult) // 「29」と表示
}add関数のfunc add(a, b int) intという部分に注目してください。a, b intは、aとbがどちらもint型であることを示します。最後のintは、この関数がint型の値を返すことを示しています。
このようにして処理をまとめておいて汎用的に管理したい時に関数を使うと便利になります。 先ほどのカレー作りでいうと、
func 食材切る(食材 食材の型) {
// 食材を切る処理
return 切った食材;
}
func 炒める(材料 材料の型) {
// 材料を炒める処理
return 炒めた食材;
}
〜〜〜のように関数を用意することで、
// カレーを作る
// ↓
切った玉ねぎ := 食材切る(玉ねぎ)
切ったにんじん := 食材切る(にんじん)
切ったジャガイモ := 食材切る(ジャガイモ)
切った肉 := 食材切る(肉)
炒めた肉 := 炒める(切った肉)
炒めた玉ねぎ := 炒める(切った玉ねぎ)
〜〜〜と実装することができます。
さらに、関数: 食材切るの処理を間違えて「微塵切り」と書いてしまったが本当は「ざく切り」だった時、この食材切る関数の中の処理だけ直せば
全てに適用される! というように関数を使うことでメンテナンスしやすい実装にすることができます。
この講座で、Goの基礎を学ぶことができました。変数、データ型、演算子、制御構文、関数といった基本的な概念を理解することで、システムチックなプログラミングへの第一歩を踏み出すことができました。これからは、これらの知識を基により高度なGoの機能や実践的なコーディングテクニックを学んでいきましょう。