Go言語入門

GO言語とは?
- 文法がシンプル
- 静的型付け言語 → 堅牢なプログラムが作成できる
- ガーベージコレクションによる自動的なメモリ管理
- メモリ安全性を持っている
- 高速な処理が得意
- コンパイル言語なので実行速度が高速
- 並列処理
- gouroutine: スレッド
- channnel: 関数間での値の送受信
以上の2つを用いることで並列処理が実現できる
環境構築
WondowsでGo言語で開発をするための環境構築を行っていこうと思います。
Go言語のインストール
まずはGo言語のSDKをダウンロードして行きましょう。
ダウンロードページからwindows用のSDKをダウンロードしていきます。
https://golang.org/dl/
以下の画像の赤枠で囲ったwindowsを選択してください。

ダウンロードが終了したらセットアップウィザードを起動しインストールを行っていきます。
ここから環境構築を対話的に行っていきますが、あまり選択することは無いのでサクサク進んでいきましょう。
セットアップウィザードの起動

ライセンス確認

インストールフォルダ指定

インストール開始

インストール終了

さてここまででインストールが終了しました。
インストールした段階で環境変数にGOPATH
というインストールしたフォルダへのパスが追加されていると思います。
環境変数を確認したい場合はコマンドプロンプトでgo env
というコマンドを入力することで一覧が確認できます。
では、Go言語がインストールされているかコマンドプロンプトで確認してみましょう。
インストールが成功していれば以下のようにgo version
と入力することでGo言語のバージョンが出てきます。

最初のHelloWorld
それでは最初に定番のHelloWorld表示をやってみます。
任意のフォルダに以下のような内容でファイルを作成します。
main関数の中で文字列を出力しているだけなので上記の基本的な構文を見ていただいた方には簡単だと思います。
package main
import "fmt"
func main() {
fmt.Printf("Hello world")
}
それでは実行してみましょう。go run
というコマンドを叩くことでGoプログラムのコンパイルと実行を行うことが出来ます。
以下のように出力されれば成功です。

基本的な構文
次に、Go言語の基本的な構文と特徴について見ていきましょう。
変数宣言
まずはGo言語における変数宣言についてです。
Go言語は静的型付け言語であるため、全ての変数が何らかの型を持っています。
そのため型関係の誤りなどはコンパイルの際に検出することができます。
基本的な宣言は以下のように行います。
// variablename: 変数名
// tyte: 変数の型
var variableName type
では変数宣言の種類について説明しします。
// hoge という変数名を定義.
// 変数の型は int
var hoge int
// 定義と同時に初期化
var hoge int = 1;
// 複数の変数を定義
// 型は全て共通
var hoge, fuga int
// 定義と同時に初期化(多重代入)
// 変数ごとの値を初期化する
var hoge, fuga int = 1, 2;
宣言では以下のような省略記法もOKです。
// := が var と type の役割を担う
// 変数の型はコンパイル時に決定される
hoge := 1
これは非常に便利な書き方なので使いたいシーンは多いと思います。
一方で、この書き方は関数の外で使用するとエラーが出るためそこだけは注意が必要です。
グローバル変数を宣言する際は必ずvar
を付けるようにしましょう。
※基本データ型
以下に変数宣言に用いる型の中から、基本データ型の型名と取りうる範囲を表にまとめました。
おおむね他の言語と同じ型が存在します。
論理値型
型 | 取りうる値 |
---|---|
bool | true, false |
数値型
- 符号付整数型: int
- 符号なし整数型: unit
型 | 取りうる値 |
---|---|
int8 | -128 ~ 127 |
int16 | -32768 ~ 32767 |
int32 | -2147483648 ~ 2147483647 |
int64 | -9223372036854775808 ~ 9223372036854775807 |
int | 32bit または 64bit (環境依存) |
unit8 | 0 ~ 255 |
unit16 | 0 ~ 65535 |
unit32 | 0 ~ 4294967295 |
unit64 | 0 ~ 18446744073709551615 |
unit | 32bit または 64bit (環境依存) |
浮動小数点型
※ double型は存在しない。float64
がdouble型と同じ倍精度浮動小数点数にあたる
文字列型
型 | 取りうる値 |
---|---|
string | 文字列 |
制御文 (if, for)
では次にif, forによる制御文の記述の仕方を説明します。
これらはプログラミングにおいて非常に重要な概念なのでしっかり覚える必要があります。
まずはif文の基本的な書き方を見ていきましょう。
// if, else if, else を用いる
var hoge int = 10
if hoge < 0 {
fmt.Println("hogeは負の値です")
} else if hoge < 10 {
fmt.Println("hogeは10未満です")
} else {
fmt.Println("hogeは10以上です")
}
// ifの中にifを書くことも出来ます
if hoge < 10 {
fmt.Println("hogeは10未満です")
if hoge < 0 {
fmt.Println("hogeは負の値です")
}
}
次は、Go言語の特徴的なif文の書き方を紹介します。
Go言語ではif文の中で変数を宣言し利用することが出来ます。
// hogeの値を取得して表示しています
// なお、この変数はこのif文の中のみで有効なので注意
if hoge := getHoge(); hoge < 0 {
fmt.Println("hogeは負の値です")
} else {
fmt.Println("hogeは正の値です")
}
比較演算子・論理演算子には以下のようなものがあります。
ここは一般的なプログラミング言語と同様です。
比較演算子 | 意味 |
---|---|
a == b | aとbが等しい |
a != b | aとbが等しくない |
a > b | aがbよりも大きい |
a >= b | aがb以上 |
論理演算子 | 意味 |
---|---|
a && b | aとbが両方とも真のなら |
a || b | aまたはbが真なら |
!a | aが偽の場合に真 |
次にfor文によるループの記述について見ていきましょう。
なお、Go言語にはC言語やJavaなどに存在するwhile文は存在しません。
なのでループの記述は全てforを使用します。
// for 初期値; 条件式; 変化式
for i := 0; i < 10; i++ {
// 処理を記述
}
// 変数宣言での多重代入を用いることで複数の宣言を使ったループが可能
for i, j := 0, 1; i > 9 && j > 10; i, j = i+1, j+1 {
fmt.Printf("i: %d, j: %d", i, j)
}
continue
やbreak
を使ってループを制御することも可能です。
for i := 0; i < 10; i++ {
// iが偶数の場合
if i % 2 == 0 {
// ここでforの先頭に戻る
continue
}
// 奇数のみ表示される
fmt.Printf("i: %d", i)
}
for i := 0; i < 10; i++ {
if i == 5 {
// for文から出る
break
}
}
また、先ほどwhileは存在しないというお話をしましたが、プログラミングをしているとどうしてもwhile文のようなループを使いたい時がくるかもしれません。
その場合はforを以下のように記述することでwhile文のようなループを作成出来ます。
count := 0
for count < 10 {
fmt.Printf("count: %d", count)
count += 1
}
0123456789
最後に、for文を使う際に、配列の中身をループさせたいと思うときがあると思います。
そのような場合Go言語では以下のような記述を行います。
for i, str := range []string{"one", "two", "three"} {
fmt.Println("%d個目: %d", i, str)
}
one
two
three
関数
ここからは関数について見ていきましょう。
基本的な宣言は以下のように行います。
// funcの後に関数名を書く
// 引数は () で指定を行う
// 引数の後に戻り値の型を記述
func functionName(variableName type) (type) {
return output;
}
Go言語では以下のように複数の戻り値を設定することができます。
これはGo言語の特徴的な性質の一つです。
あまり馴染みがないと思いますが、使いこなせば非常に便利な機能になっています。
// 以下のように複数の戻り値を設定することが出来ます。
func functionName(valiableName1 type1, valiableName2 type2) (type1, type2) {
return output1, output2;
}
// 使用例
func calc(a int, b int) (int, int) {
return a+b, a-b;
}
func main() {
var a int = 2;
var b int = 3;
add, minus := calc(a, b);
fmt.Println("add: %d", add)
fmt.Println("minus: %d", minus)
}
add: 5
minus: -1
戻り値が多くなった場合は以下のように戻り値を名前付きで設定することも可能です。
// 戻り値に名前を付けられます
// また、引数、戻り値の型が同じなら (a, b int) のようにまとめて記述できます
func calc(a, b int) (add, minus, multi, div int) {
add = a+b
minus = a-b
multi = a*b
div = a/b
return
}
構造体
次に構造体の話をしていきます。
Go言語には、いわゆるオブジェクト指向のクラスというものが存在しません。
その代わりとして構造体というデータ型があり、複数の変数やメソッドを格納することが出来ます。
基本的な宣言は以下のように行います。
// このように変数を格納できます
type structName struct {
variableName1 type1
variableName2 type2
}
// メソッドは以下のように定義します
// func(レシーバ 型) 関数名() 戻り値の型 {処理}
func (receiver structName) functionName() outputType {
return variableName1;
}
メソッドの定義でレシーバを付けるというところに注意が必要です。
レシーバを付けないとただの関数になってしまうので忘れないようにしましょう。
使用例
type Animal struct {
name string
cry string
}
func (animal Animal) about() string {
return name + "の鳴き声: " + cry
}
func main() {
// 構造体の宣言
var dog Animal
// 変数の初期化は全部で3通りあります
// 特にこれを使うべきという決まりは無いので開発方針に合わせて使い分ければOK
// 1. ドット(.)でのアクセス
dog.name = "犬"
dog.cry = "わんわん"
// 2. {} で値を渡す
dog := {"犬", "わんわん"}
// 3. コロン(:) で指定
// 引数名を指定するため分かりやすい
dog = Animal{name: "犬", cry: "わんわん"}
// メソッドへのアクセスはドット(.)で行います
fmt.Println(dog.about())
}
犬の鳴き声: わんわん
まとめ
Go言語の入門ということで基本的な構文を紹介しました。実践では、goroutine
とchannel
を用いた並列処理など、テクニカルな内容もあります。
詳しくは以下の参考文献などをご覧ください。