Go言語の言語特性を学ぶ

#はじめに
![uchiha_gopher - コピー - コピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406684/5ce505ff-ff4f-e44e-7c67-6e36b4bc309a.jpeg)
>[The Go gopher](https://blog.golang.org/gopher) was designed by [Renée French](http://reneefrench.blogspot.com/).
["Kakashi's mangekyou sharingan"](https://ja.wikipedia.org/wiki/%E8%A1%80%E7%B6%99%E9%99%90%E7%95%8C#mediaviewer/File:Mangekyou_Sharingan_Kakashi.svg) by [ShounenSuki](https://en.wikipedia.org/wiki/User:JadziaLover) is licensed [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)

この記事は、Go言語を学ぼうとしているエンジニアが
Go言語の基語特性を学ぶことを目的としています。

私はGo言語の経験は無いのですが、事情により今後使用することになりそうですので、
どうせなら最初に言語特性を学びたいと思い、調べてみました。

#Go言語の概要
Go言語とは、2009年にGoogleが公開したオープンソースの手続き型プログラミング言語です。
プログラミング言語研究のための言語ではなく、
<font color="Red">**問題解決にフォーカスしたプログラミング言語**</font>として世界的に高い人気があります。
規模の大きなプロジェクトに向いており、
システムやネットワーク、サーバーサイド、CUIツールでは定番言語の一つになりつつあり、
日本でのユーザー数も増えているそうです。

設計方針としては、既存の言語の良いところを取り入れ、必要性の低いところは除き、
より安全で効率よくプログラムを書くことを目標としております。
また、実行形式はコンパイラ型でして、構文はC言語が基になってます。

#Go言語の目標
・言語をシンプルに保つ
・コンパイル速度の向上
・実行速度の向上
・並列実行を言語としてサポート
・ガベージコレクション
・型間の関係性を定義する時間をなくす（継承がない）

#Go言語が作られた背景
・Google社内における大規模ソフトウェア開発の生産性や拡張性を高めるため。

#Go言語の特徴
・シンプルな言語仕様
　　多くの言語は同じような機能追加競争を行い、似通った言語になりつつあります。
　　その一方、Go言語は機能を削ることでシンプルさに徹底的に拘っています。
　　コア開発者の全員が必要だと思った機能しか言語に取り込まないという方針が、
　　シンプルさに寄与していると言えます。

・コンパイルが高速
　　C言語系のコンパイラに比べ、コンパイル速度が速くなっています。
　　C言語のようなインクルードを採用しなかったことで、
　　コンパイル時のオーバーヘッドが削減されました。
　　（インクルードは指定したファイルを丸ごとそこへ挿入する。
　　　なので、インクルードが増えるほどビルド時間の増大に繋がる。）

・クロスコンパイルをサポート
　　マルチプラットフォームに対応したクロスコンパイルをサポートしています。
　　例えば、ソースからWindows用、Mac用、Linux用などのバイナリを生成できます。
　　マルチプラットフォームで有名なJava言語の場合はClassファイルを生成してJVMで実行しますが、
　　Go言語の場合は各環境で直接実行できます。
　　Java言語のスローガンが「Write once, run anywhere」なら、
　　Go言語は「Write once, compile anything」といったところでしょうか。

・並列処理を言語としてサポート
　　並列処理を言語としてサポートしているため、複数の処理を同時に実行できます。
　　（関数の呼び出し時、先頭に「go」を付けるだけ）
　　この並列処理は「ゴルーチン」と呼ばれる仕組みであり、独立して動作する実行単位でもあります。

・ガーベジコレクション
　　メモリの未使用領域が自動的に開放されます。
　　なのでソースでのメモリ管理が不要になり、メモリリークを抑制できます。

・安全性が高い
　　C言語と同じポインタがありますが、不正なメモリアクセスができないように、
　　ポインタの演算はできません。
　　また、型のチェックも厳密に行われるため、バグによってメモリが壊される危険性を回避しています。

・継承がない
　　Java言語のような一般的なオブジェクト指向言語で用いられる「クラス」がありません。
　　よって、継承という概念がありません。
　　その代わりに「埋め込み」や「インタフェース」とった仕組みが用意されています。

・例外がない
　　Java言語等の多くの言語で採用されている「try～catch」による例外処理機構がありません。
　　ならば、Go言語はどのようにエラーハンドリングをしているかというと、
　　前提として、Go言語の関数は「複数個の値」を戻り値として返せます。
　　なので、エラーハンドリングは必要に応じて
　　関数の実行結果と一緒にエラー情報を返すことにより実現しています。

#Go言語でデキること
・Webアプリ開発
　　[net/http](https://golang.org/pkg/net/http/)パッケージを使用してHTTPサーバーを簡単に構築できますので、Webアプリを開発できます。
　　YouTubeなどのWebアプリにもGo言語が使われています。
　　例えば、下記を１行書くだけでHTTPサーバーをポート8080で起動できます。

```go:net/httpパッケージ
    http.ListenAndServe(":8080", nil)
```

・スマホアプリ開発
　　AndroidやiOSのアプリ開発用に[モバイルパッケージ](https://github.com/golang/go/wiki/Mobile)が用意されており、
　　スマホで動作するネイティブアプリケーションを開発できます。

・CUIツール開発
　　CUI (Character User Interface) と呼ばれる入力インターフェースで、
　　コマンドで命令を入力して処理を実行するツールを開発できます。
　　例えばWindowsでいうコマンドプロンプト、Macでいうコマンドラインのようなものが開発できます。

#Go言語が使われているサービス
・[AbemaTV：国内最大の無料インターネットテレビ局](https://abema.tv/)
・[クックパッド：レシピ検索No.1／料理レシピ載せるなら クックパッド](https://cookpad.com/)
・[Cacoo：フローチャートが作れるオンライン作図ツール](https://cacoo.com/ja/)
・[グノシー：無料で読めるニュースまとめ](https://gunosy.com/)
・[BASE (ベイス)：ネットショップを無料で簡単に作成](https://thebase.in/)

#Go言語で簡単なプログラム実行・ビルド
せっかくなので、Go言語で簡単なプログラムを作成して実行やビルドをしてみます。
##前提
・[Go言語(1.12.0)](https://golang.org/dl/)がインストール済みであること。

##基本知識
・拡張子は「.go」
・文字エンコードはUnicodeの「UTF-8」
・アルファベットの大文字と小文字は異なる識別子として扱われる
・何らかのパッケージに属している必要があり、1つは必ずmainパッケージでなければならない
・最初にmainパッケージ内のmain()関数が実行される
・関数宣言のような波括弧「{}」は、開始波括弧「{」を同じ行に書く必要がある
・タブ区切り推奨
・セミコロンなし推奨(1つの行に複数の文を記述する場合は明示しなければならない)

##準備
次の手順でGo言語で作成したソースファイルを準備します。

**■手順**
　1.コマンドプロンプトを起動

　2.以下のコマンドを実行し、Cドライブの直下にディレクトリを作成

```console:コマンドプロンプト
mkdir C:\workspace_go\main
```

　3.「C:\workspace_go\main」直下へ、以下のソースファイル「hello.go」を配置

```go:hello.go
// このソースファイルは「main」パッケージに属すことを指定しています。
// また、Go言語のソースファイルは必ず「package」文で始まります。
package main

// 標準ライブラリであるパッケージ「fmt」をインポートしています。
// 「fmt」はフォーマットI/Oを実装しており、C言語のprintfおよびscanfと似た関数を持ちます。
import "fmt"

// 「func」が関数の宣言で、ここから「main」関数の記述が始まります。
// ※関数宣言のような波括弧「{}」は、開始波括弧「{」をfuncと同じ行に書く必要があります。
func main() {

	// インポートした「fmt」パッケージ内の「Print」関数を使用し、標準出力に「Hello world!」と出力します。
	fmt.Printf("Hello world!\n")
}
```

##実行

```console:コマンドプロンプト
go run C:\workspace_go\main\hello.go

Hello world!
```

##ビルド

```console:コマンドプロンプト
go build C:\workspace_go\main\hello.go
C:\workspace_go\main\hello

Hello world!
```

# 参考にしたサイト
・Go言語の公式サイト：[The Go Programming Language](https://golang.org/)
・Go言語の公式サイトの日本語訳：[プログラミング言語Goの情報サイト](http://golang.jp/)
・Go言語のfmtパッケージ仕様：[パッケージドキュメント](http://golang.jp/pkg/fmt)
・stackoverflow：[Developer Survey Results 2019](https://insights.stackoverflow.com/survey/2019/#overview)

# おわりに
Go言語の設計思想や特徴について学ぶことができました。

調べていく中で、Go言語は設計思想が合理的で、
現代のニーズにマッチしている（下から目線）と感じました。
その理由は、Go言語は既存の言語の良いところを取り入れつつも、必要性の低いところは取り除き、
かつ、現代のシステム開発における問題を解決するための機能を提案し実現しようとしているという、
本当に問題解決にフォーカスしたプログラミング言語なのだなと思ったからです。

次回は、Go言語のアプリをGCPにデプロイするまでの流れについて投稿しようと思います。