5分で学ぶ気になるプログラミング言語（Go編）

※他の記事はこちらになります。あわせてご覧ください
[5分で学ぶ気になるプログラミング言語（Rust編）](https://qiita.com/kansaizine/items/f17c56ce653e8131c9e8)
[5分で学ぶ気になるプログラミング言語（Nim編）](https://qiita.com/kansaizine/items/58e694ea9c35686cfd39)

## 5分で学ぶGo
それでは今回はGoを学んでいきます。5分しかないので急ぎましょうｗ

Goの公式サイトのURLは https://golang.org/ です。
「Go」という単語はググラビリティ的に難がありますが、「Golang」という呼称も結構浸透しているかなと思います。
「ゴー」って、言いやすいので好きですねｗ　発音で悩まないというのは日本人的には重要かと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157692/03b7f996-7425-6eca-79ac-314f30358037.png)

Rustでは日本語サイトが提供されていましたが、Goは硬派に英語のみです。ひるまずいきましょうｗ

Rustでもそうでしたが、Goもファーストビューで特徴が語られています。
それによると、Goは「シンプルで信頼性が高く、効率的なソフトウェアを簡単に構築できるオープンソースのプログラミング言語」とのことです。Rustと同じ様な特徴を持っていましたが「シンプル」というのはGoのイメージとして強い部分だと思います。

Goはファーストビューに「Try Go」というプレイグラウンドのコンテンツがあるので、ここにコードを書いて「Run」を押すとリモートサーバ側で実行されすぐに結果を見ることが出来ます。まぁここでプログラミングする人はそんなに居ないと思いますが、インストールせずにすぐに試せるのはよいですね！

メニューを見渡すと「Documents」と「Play」というのが学習系コンテンツだと思われますが、まだ「Play」するだけの知識がないので「Documents」から見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157692/246b8997-3402-e018-f729-8512d507b9dd.png)

最初に「Getting started」というカテゴリがあり、幾つかのコンテンツが用意されています。「Installing Go」については、[前回](https://qiita.com/kansaizine/items/f17c56ce653e8131c9e8)に決めた通りインストールはパッケージマネージャを使用することとしていますのでスキップします。

「Tutorial: Getting started」とチュートリアルコンテンツが良さそうなので見てみます。このチュートリアルを行うと以下の様な体験が出来ると書かれています。この様に、学習の前段でどの様な結果が得られるかを先に説明することは非常に分かりやすいと思います。

* 「Hello, world」のコードを書く
* goコマンドを使ってコードを実行する
* Goパッケージのツールを使ってパッケージを探し自分のコードで使用する
* 外部モジュールの関数を使用する

それではやっていきましょう。

「3.Enable dependency tracking for your code.」では、依存性の管理のための準備の方法が紹介されています。「dependency tracking」の詳細はまだ理解できていませんが、他の言語やフレームワークでも導入されている外部モジュールの管理機能と同じものだと思われます。ここではチュートリアルの指定通り下記のコマンドを実行しておきます。

```bash
$ go mod init example/hello
go: creating new go.mod: module example/hello
```

次にHello, worldのコードを書きます。例が示されていますので写経します。

```golang:hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
```

最初に「package」として「main」が宣言されていますが、こちらはいわゆる名前空間を表すものだと思います。「main」というワードに特別な意味があるのかはまだ分かりません。次に「import」が記述されていますが、これは外部モジュールをインポートする命令でしょう。「fmt」というのはいわゆる文字列のフォーマット等を扱うモジュールだと思われます。

そしてmain関数があり、中でHello, worldの文字列を出力しています。この辺りの流れはどの言語でもほぼ同じですね。Rustでは関数宣言は「fn」でしたがGoでは「func」ですね。個人的には後者の方が好みです。ブロックはRustと同じ波括弧となっていますが、行末のセミコロンは省略できる様です。コードを書く際にマルチステートメントを使用することは殆ど無くなってきているので、個人的には賛成です。

続いて「main」に関する説明があり、Goでは「main」パッケージの「main」関数がエントリポイントになっているとのことです。何かコードを書く時はまずはこのフォーマットのコードでスタートするということですね。

それでは書いたコードを実行します。

```bash
$ go run .
Hello, World!
```

「go」コマンドに「run」というパラメータと「.」というパラメータを渡して実行しています。「run」は分かるとして「.」の方は普通に考えると実行するファイル名を指定することになると思いますが、カレントディレクトリを指定している様です。先程Goが「main」パッケージの「main」関数を実行することを学びましたが、カレントディレクトリを指定することでそれを含むコードを探して実行してくれるということでしょうか。この辺りはまた追々学んでいくことになるのかなと思います。

ここでチュートリアルの流れからは若干逸れますが、「go」コマンドでどんなことが出来るのか把握するためにパラメータ無しで実行してみます。

```bash
$ go
Go is a tool for managing Go source code.

Usage:

        go <command> [arguments]

The commands are:

        bug         start a bug report
        build       compile packages and dependencies
        clean       remove object files and cached files
        doc         show documentation for package or symbol
        env         print Go environment information
        fix         update packages to use new APIs
        fmt         gofmt (reformat) package sources
        generate    generate Go files by processing source
        get         add dependencies to current module and install them
        install     compile and install packages and dependencies
        list        list packages or modules
        mod         module maintenance
        run         compile and run Go program
        test        test packages
        tool        run specified go tool
        version     print Go version
        vet         report likely mistakes in packages

Use "go help <command>" for more information about a command.

Additional help topics:

        buildconstraint build constraints
        buildmode       build modes
        c               calling between Go and C
        cache           build and test caching
        environment     environment variables
        filetype        file types
        go.mod          the go.mod file
        gopath          GOPATH environment variable
        gopath-get      legacy GOPATH go get
        goproxy         module proxy protocol
        importpath      import path syntax
        modules         modules, module versions, and more
        module-get      module-aware go get
        module-auth     module authentication using go.sum
        packages        package lists and patterns
        private         configuration for downloading non-public code
        testflag        testing flags
        testfunc        testing functions
        vcs             controlling version control with GOVCS

Use "go help <topic>" for more information about that topic.
```

ズラっとコマンドリストが表示されました。先程使った「run」コマンドも一覧にありますがここで興味深いのは「build」コマンドです。どうやらGoもRustと同じくバイナリを生成する機能を持っている様です。先程実行した際には「run」コマンドで実行しましたが、バイナリを生成して直接実行することも可能となると、スクリプト（インタプリタ）言語の簡単さとコンパイラ言語の両方の特徴を兼ね備えた便利な言語であると言えると思います。

次のセクションでは「Call code in an external package」として、外部モジュールを使ったコードの実行を学びます。
まずは外部モジュールを探すために [pkg.go.dev](https://pkg.go.dev/)にアクセスして、キーワードで検索する方法が提供されます。このサイトはGoの公式サイトの一部の様ですが、使用したいモジュールをキーワードで探す方法が公式として提供されていることは、迷いが生まれずに済みますので非常によいと思います。

チュートリアルでは「rsc.io/quote」という外部モジュールを使用することになっています。いわゆる[fortune](https://ja.wikipedia.org/wiki/Fortune_(UNIX))コマンドと同じ動きをするものの様ですね。先程書いたHello, worldのコードを変更して、表示するメッセージを「rsc.io/quote」パッケージの「quote.Go()」関数に差し替えます。

```golang
package main

import "fmt"

import "rsc.io/quote"

func main() {
    fmt.Println(quote.Go())
}
```

次に、「go mod tidy」コマンドを実行して、モジュールをダウンロードします。

```bash
$ go mod tidy
go: finding module for package rsc.io/quote
go: found rsc.io/quote in rsc.io/quote v1.5.2
```

「tidy」というのもどういう意味か確認しておきましょう。

```bash
$ go mod
Go mod provides access to operations on modules.

Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.

Usage:

        go mod <command> [arguments]

The commands are:

        download    download modules to local cache
        edit        edit go.mod from tools or scripts
        graph       print module requirement graph
        init        initialize new module in current directory
        tidy        add missing and remove unused modules
        vendor      make vendored copy of dependencies
        verify      verify dependencies have expected content
        why         explain why packages or modules are needed

Use "go help mod <command>" for more information about a command.
```

必要なモジュールを追加したり、使用されていないモジュールを削除してくれるコマンドの様ですね。
全体的に、必要なツールが過不足なく用意されていて、効率よく開発が行えそうだなという印象を受けます。

最後に変更後のコードを実行してみると、rsc.io/quote パッケージの戻り値を受け取った内容に変化していました。

```bash
$ go run .
Don't communicate by sharing memory, share memory by communicating.
```

## 学べたこと
5分過ぎてないか？と言われそうですがｗ、今回Goについて下記のことが分かりました。

### Goはコンパイラ型言語である
Goは、ソースコードを記述してそれをgoコマンドで直接実行もできつつ、コンパイルして実行バイナリを生成することもできる、コンパイラ型言語であることが分かりました。Rustも同じ特徴を持っていましたが、コンパイラ型であることでポータビリティに優れていたり、パフォーマンス上の優位性があったり、適用できるシーンが増えることが期待できます。

### Goはビルドシステムとパッケージマネージャを内包している
Goは専用のビルドシステムとパッケージマネージャを言語として持っています。言語には含まれず、別途アプリケーションとして配布されるケースも多くありますが、更新頻度やプロジェクトの継続性等の観点でやや不安は残りますので、言語としての配布に内包されているというのは安心できる要素だと思います。

### Goは公式の学習コンテンツが充実している
今回試してみたチュートリアルの他、[「A Tour of Go」](https://tour.golang.org/list)という学習コンテンツがあり、初期学習の大きな助けになります。このコンテンツはさすがに5分ではなくしっかり時間を取って学ぶことをおススメしますが、コードを書いてその結果を確認しながら学べる様になっていて、書籍等で説明やコードを「見る」だけで学ぶのに比較して、習得はこちらの方が早いと個人的には思います。

### あれ…？
なんと、学べたことはRustとほぼ同じですね…ｗ
ある意味、各言語とも同じ様な特徴を持っていてそれが現代のプログラミング言語ではスタンダードであると言えるかと思います。また、プログラミング言語はある程度時間をかけて学ばなければならない分スイッチングコストが大きいものとなりますが、それをサポートする様に学習コンテンツについても力が入れられているなということが分かりました。

## 次回
次回は3部作の最後、Nimを学びたいと思います。