
前回のおさらい
前回は、変数、型、if 文、for 文、switch 文について学びました。今回は、コードを「まとめて整理する」ための2つの仕組み、関数とパッケージについて学びます。
関数ってなに?
前回のコードでは、fmt.Println(...) という命令を何度も使いました。この Println は、実は 関数(かんすう) と呼ばれるものの1つです。
関数とは、ひとことで言うと 「ひとまとまりの処理に、名前をつけたもの」 です。
たとえば、料理のレシピを思い浮かべてください。「カレーの作り方」というレシピには、「野菜を切る」「炒める」「煮込む」といった手順が書かれています。この「野菜を切る」という手順に、毎回細かいやり方を書く代わりに、「野菜を切る」というレシピ(手順書)を1つ作っておいて、必要なときにそれを呼び出す、というイメージが関数です。
プログラムでも同じように、「よく使う処理」や「意味のあるまとまりの処理」に名前をつけておくことで、
- 同じコードを何度も書かなくてよくなる(コピペが減る)
- 「この部分は何をしているコードなのか」が名前だけでわかりやすくなる
- 修正するときも、その関数の中身を直せば、使っている場所すべてに反映される
といったメリットがあります。
関数を作ってみよう
実際に、自分で関数を作ってみましょう。「2つの数字を受け取って、その合計を返す」という関数を作ります。
package main
import "fmt"
func add(a int, b int) int {
sum := a + b
return sum
}
func main() {
result := add(3, 5)
fmt.Println(result)
}
実行結果は次のようになります。
8
func add(a int, b int) int { ... } を、1つずつ日本語に置きかえてみましょう。
func→ 「これから関数を定義しますよ」という宣言add→ 関数の名前(自分で好きな名前をつけられます)(a int, b int)→ この関数が受け取る材料(引数、ひきすうと読みます)。「aという名前のint型の値」と「bという名前のint型の値」の、2つを受け取るという意味です- 最後の
int→ この関数が最終的に返す値の型(戻り値の型)。「int型の値を1つ返しますよ」という意味です { ... }の中 → 実際の処理内容return sum→ 「sumの値を、この関数の結果として返します」という意味
main 関数の中にある add(3, 5) の部分で、実際に add 関数を呼び出しています。「aに3を、bに5を渡して、add関数を実行してください」という意味です。add関数の中では sum := a + b によって 3 + 5 = 8 が計算され、return sum によってその 8 という結果が呼び出し元に返されます。それを result という変数で受け取り、fmt.Println(result) で表示しているので、8 と表示される、というわけです。
引数がない関数、戻り値がない関数
すべての関数が、材料(引数)や結果(戻り値)を持つわけではありません。
package main
import "fmt"
func greet() {
fmt.Println("こんにちは!")
}
func main() {
greet()
}
greet 関数は、材料(引数)を受け取らず、結果(戻り値)も返さず、ただ「こんにちは!と表示する」という処理だけを行います。関数名のあとの () が空っぽで、戻り値の型も書かれていない点に注目してください。
Goならではの機能: 複数の値を返せる
多くのプログラミング言語では、関数が返せる値は1つだけです。しかしGoでは、1つの関数から複数の値を同時に返すことができます。これはGoの大きな特徴の1つです。
package main
import "fmt"
func divide(a int, b int) (int, int) {
quotient := a / b // 商(わり算の答え)
remainder := a % b // 余り
return quotient, remainder
}
func main() {
q, r := divide(17, 5)
fmt.Println("商:", q)
fmt.Println("余り:", r)
}
実行結果は次のようになります。
商: 3
余り: 2
(int, int) のように戻り値の型を2つ並べることで、「int型の値を2つ返しますよ」という意味になります。呼び出す側では q, r := divide(17, 5) のように、2つの変数を同時に受け取ることができます。
この「複数の値を返す」という機能は、実はGoではとてもよく使われます。次回以降に何度も登場する「エラー(処理がうまくいかなかったことを表す値)」も、多くの場合「本来欲しい値」と「エラー」の2つをセットで返す、という形で扱われます。
パッケージってなに?
続いて、パッケージについて説明します。
第1回で、main.go の一番上に package main と書きました。また import "fmt" という行もありました。これらが、パッケージに関係する部分です。
パッケージとは、ひとことで言うと 「関連する関数や機能をまとめた、部品の集まり」 です。
たとえば工具箱をイメージしてください。工具箱の中には、ドライバー、ペンチ、ハンマーなど、いろいろな工具が種類ごとに整理されて入っていますよね。パッケージも同じで、「文字列を扱う機能をまとめたパッケージ」「数学の計算をまとめたパッケージ」のように、関連する機能ごとにグループ分けされています。
Goには、あらかじめたくさんの便利なパッケージが用意されています。これを標準ライブラリと呼びます。第1回・第2回で使った fmt パッケージ(文字の表示など)もその1つです。他にも、次のようなパッケージがあります。
strings→ 文字列を操作するための機能(大文字/小文字の変換、文字列の分割など)strconv→ 文字列と数値を相互に変換するための機能math→ 数学の計算(平方根、絶対値など)のための機能time→ 日付や時刻を扱うための機能
これらを使いたいときは、import を使って「このパッケージを使いますよ」と宣言します。実際に strings パッケージを使ってみましょう。
package main
import (
"fmt"
"strings"
)
func main() {
name := "go language"
upper := strings.ToUpper(name)
fmt.Println(upper)
}
実行結果は次のようになります。
GO LANGUAGE
strings.ToUpper(name) は、「stringsパッケージの中にあるToUpper(すべて大文字に変換する)という機能に、nameを渡して実行する」という意味です。fmt.Println のときと同じように、「パッケージ名.機能名(材料)」という形で、パッケージの中の機能を呼び出します。
複数のパッケージを使うときは、上のコードのように import ( ... ) の中に、1行ずつパッケージ名を並べて書きます。
package main の意味、もう一度
第1回で少しだけ触れた package main について、ここでもう一度確認しておきましょう。
Goのファイルは、必ずどこかのパッケージに属していて、ファイルの一番上に package パッケージ名 と書く決まりになっています。その中でも main という名前のパッケージは特別で、「このプログラムを実行したときの、スタート地点になるパッケージ」という意味を持ちます。mainパッケージの中の main 関数が、プログラムが実行されたときに最初に呼び出される処理になる、というわけです。
まとめ
今回は、以下のことを学びました。
- 関数は「ひとまとまりの処理に名前をつけたもの」で、材料(引数)を受け取り、結果(戻り値)を返すことができる
- Goの関数は、複数の値を同時に返すことができる(他の多くの言語にはない特徴)
- パッケージは「関連する機能をまとめた部品の集まり」で、
importを使って利用する fmt、stringsなど、Goには最初から便利なパッケージ(標準ライブラリ)がたくさん用意されている
関数とパッケージは、コードを整理し、再利用しやすくするための、とても基本的で大切な仕組みです。次回は、複数のデータをひとまとめにして扱う構造体と、それに関連するインターフェースという考え方を学んでいきます。
次回:「Go言語入門④構造体とインターフェース編」お楽しみに。


