ITと雑記とド田舎と

ド田舎在住エンジニアがIT備忘録と雑記を書くブログです

Go(Golang)についてまとめてみる

Goについてまとめてみる

最近Golangを触り始めたので、備忘録兼自分の刷り込みようにまとめます。

マスコットキャラのGopher君がかわいい

f:id:kdn-1017-wttd:20191218231202p:plain
The Go gopher was designed by Renée French.

このデザイン個人的にツボです。ライセンスもCC BY 3.0という自由度の高いライセンスになっており、上の画像のように作者のRenée French氏のクレジットを掲示すれば自由に使用可能なのだそうです。

Golangの基本

それぞれについて分かる範囲で記述していきたいと思います。

2009年にGoogleで設計

2009年にGoolgeのロバート・グリーズマー、ロブ・パイク、ケン・トンプソンが設計した。 ロプ・パイク氏はカナダ出身のソフトウェア工学者でベル研究所UNIXを開発している。 ケン・トンプソン氏も同様にベル研究所UNIXの開発を行っており、そのほかにもB言語を設計。 後に同研究所に所属していたのデニス・リッチー氏がB言語にデータ型と新たな文法等を追加してC言語を開発している。(Wikipediaより)

GCPの対応言語のひとつでそのほか有名なサービスやOSSの開発に利用されています。
日本のサービスだとメルカリやクックパッド、Lineの一部ツールやサービス、OSSだとdocker,kubernetesが有名ですね。

コンパイル言語

コンパイル言語なので実行バイナリファイルが作られます。コンパイルも速いそうです。
もちろん実行速度も速いです。公式にも「表現に富み、簡潔で効率的」と書かれています。
まだ公式チュートリアルA Tour of Goを行っている途中ですがCやC++と比べて分かりやすい印象です。
私は学生の頃の研究はすべてC言語で書いていましたが、C言語の経験があれば抵抗なく始められると思います。

ガベージコレクション(GC)

JavaPythonなどの言語でも行われる自動的にメモリが開放される機能です。
私も知識がないので全く詳しい説明はできないですが、Goで採用されているのはConcurrent Mark & Sweepと呼ばれるシンプルなガベージコレクションだそうです。
Markでポインターをたどって使用されているオブジェクトにマークをしていき、Sweepでマークがついていないオブジェクトを空き領域にするという方式で、これをメモリの開放が終了するのと同時にマーキング処理を行うスレッドを並行して実行するためConcurret Mark & Sweepとのこと。

JavaGCはこれに加えてコンパクションや世代別GCと呼ばれる機能を持っています。
C言語などだとすべて自分でメモリ管理をしなければいけないので大変ですよね。組み込み開発だと必須スキルだと思います。
しかし、私の場合はそこまで意識する必要がない場合がほとんどなのでやはりGCはありがたいです。

メモリ安全

メモリエラーを回避するような実装がされているらしい。
バッファオーバーフローメモリリークなどをメモリ安全がないC言語などのように意識しなくても良いということだと思います。
ポインターは存在していますが、Cのようにポインタ演算ができないです。これもメモリ安全のための仕様でしょう。

構造的型付け

A Tour of Goを進めればわかるのかもしれないですが、よくわかっていません。
classが無いけどC言語の構造体のような物を利用して継承のようなことが出来るらしいです。
理解が進めば追記しようと思います。

並列処理が得意

  • GoroutineとChannelを使った並列処理。
  • CoroutineでもThreadでもProcessでもなく、複数Thread上に多重化されて実装されている。
  • Threadと比べて省メモリ(windows 1MB, Linux2MB, goroutin最小2048byte)
  • Threadよりも切り替えが高速。
  • main関数やGCもGoroutineで動いている。
  • Chanenelはメッセージパッシングを行うための物。多分Process間の共有メモリのような仕組みだと思います。
  • selsectを使って複数のchannelの値を同時に受け取れる。
  • close()でchannelを任意に閉じることができる。
  • Goroutineはtime.Afterでタイムアウトできる。
  • channelに一度に書き込める上限値を決められる。
  • goroutineの数を制限するGOMAXPROCSでCPUのコア数を指定するのが良い(Go 1.5以降だと自動で最適設定される)

ロスコンパイル

単一のソースコードからOS関係なくコンパイルが可能です。さらにWindowsLinuxのバイナリを生成するなどプログラミングしているOSを問わずコンパイルができます。32bit CPUで64bit CPUのバイナリを生成することもできるようです。

ロスコンパイル方法は以下

$ GOOS=linux GOARCH=amd64 go build hello.go

参照