書籍概要

エンジニア選書

Go言語プログラミングエッセンス

著者
発売日
更新日

概要

Go言語ユーザーとして,「もう一段レベルアップしたい」「開発に使いたい」と思っている方に向けた,Go言語の解説本です。関数やパッケージの使い方,並行処理,テストといった基本的なトピックにおいて,「こう書くと綺麗になる」「こう書くとパフォーマンスが上がる」といったエッセンスを紹介します。後半ではCLIアプリ/Webアプリの開発手順や,現場で使われている便利なパッケージなど,著者が業務やOSSの開発で培った技術をふんだんに紹介します。

こんな方におすすめ

  • Go言語の入門を終え,さらに深く学びたい人

サンプル

samplesamplesample

目次

第1章 プログラミング言語Goとは

  • 1.1 Goの簡単な歴史
  • 1.2 Goの立ち位置
  • 1.3 Goが利用される場面
    • 標準でUTF-8をサポート
    • マルチプラットフォーム
    • 並行処理の扱いやすさ
    • ストリーム指向
    • シングルバイナリ
  • 1.4 教育用途としてのGo
  • 1.5 なぜGoが使われるのか
    • コンパイルの速さ
    • レビューのしやすさ
    • 周辺ツールの充実
    • パッケージ公開の簡単さ
    • libc非依存
    • 共同開発でのスキル差
  • 1.6 まとめ

第2章 開発環境の準備

  • 2.1 Goコンパイラのインストール
    • [COLUMN]GOROOT? GOPATH?
  • 2.2 開発環境のセットアップ
    • Visual Studio Code
    • Vim
    • Goland
  • 2.3 まとめ

第3章 基本的な文法

  • 3.1 プロジェクトフォルダ
  • 3.2 Go言語の特徴
  • 3.3 静的な型
  • 3.4 基本的な構文
    • 変数宣言
    • const(定数宣言)
    • iota(列挙)
    • 命名規則
    • 関数呼び出し
    • 条件分岐
    • ループ
    • 配列とスライス
    • 文字列
    • map
    • type(型宣言)
    • struct(構造体)
    • メソッド
    • ポインタ
    • interface{}またはany
    • コンストラクタ
    • インターフェース
    • defer
  • 3.5 goroutine(ゴルーチン)
    • channel(チャネル)
    • 制御構文(select)
  • 3.6 Goモジュールとは
    • go.modの配置
    • replace
    • go install
  • 3.7 プロジェクトレイアウト
  • 3.8 lint文化
    • go vet
    • revive
    • golangci-lint
  • 3.9 go fmt
  • 3.10 まとめ
    • [COLUMN]おまじない

第4章 基本テクニックとベストプラクティス

  • 4.1 ビルトイン関数
    • printとprintln
    • panicとrecover
    • [COLUMN]Explicit is better than implicit, Simple is better than complex
    • init関数
  • 4.2 パッケージ
    • fmtパッケージ
    • logパッケージ
    • encoding/jsonパッケージ
    • netパッケージ
    • timeパッケージ
    • pathパッケージとpath/filepathパッケージ
    • osパッケージ
    • ioパッケージ
    • contextパッケージ
  • 4.3 build constraints
    • ファイル名による指定
    • +build(またはgo:build)コメントによる指定
    • [COLUMN]マルチプラットフォーム向けアプリケーションの開発テクニック
  • 4.4 cgo
    • pkg-configを使って複雑なコンパイルオプションに対処
  • 4.5 go:embed
  • 4.6 Functional Options Pattern
  • 4.7 Builder Pattern
  • 4.8 internalパッケージ
  • 4.9 Embedded struct
  • 4.10 go run
  • 4.11 まとめ

第5章 Webアプリケーションの開発に必要な要素

  • 5.1 net/http
    • 基本の使い方
    • ルーティング
    • [COLUMN]Method Value
    • ファイルのサーブ
  • 5.2 html/template
    • struct
    • range/end
    • if/else/end
    • with/else/end
    • template.HTML
    • FuncMap
    • template.Parse
    • define/template
  • 5.3 net/smtp
  • 5.4 まとめ

第6章 速いプログラムのためのテクニック

  • 6.1 並行と並列
  • 6.2 goroutine
  • 6.3 channel
  • 6.4 非同期パターン
    • ジェネレータ
    • 合流処理
    • 先着処理
    • タイムアウト処理
    • 停止処理
    • スロットリング(throttling)
  • 6.5 まとめ

第7章 テストにおけるテクニック

  • 7.1 テストの考え方
  • 7.2 Goのテストの基本
    • Table Driven Tests
    • t.Skip/t.Skipf
    • setup/teardown
    • t.Short
    • t.Parallel
    • テストデータ
    • カバレッジ
  • 7.3 便利なテクニック
    • テンポラリディレクトリ
    • 環境変数
  • 7.4 Fuzzingテスト
  • 7.5 まとめ

第8章 ベンチマークにおけるテクニック

  • 8.1 「推測するな、計測せよ」
  • 8.2 ベンチマークの基本
  • 8.3 ベンチマークの比較
    • 改善の前と後の比較
    • 異なる実装の比較
  • 8.4 プロファイリング
  • 8.5 まとめ

第9章 GoによるCLIアプリケーション開発

  • 9.1 システムのコンセプト
  • 9.2 データベース登録プログラム
    • [COLUMN]プログラムを作る手順
    • ZIPファイルのURL一覧を得る
    • ZIPファイルを展開する
    • データベースに登録する
  • 9.3 データベース照会プログラム
  • 9.4 テストの実装
  • 9.5 CLI開発に役立つライブラリ
  • 9.6 フラグライブラリ
    • flagパッケージ
    • urfave/cli
    • alecthomas/kingpin
    • spf13/cobra
  • 9.7 端末制御ライブラリ
    • olekukonko/tablewriter
    • mattn/go-runewidth
    • jroimartin/gocui
  • 9.8 まとめ

第10章 GoによるWebアプリケーション開発

  • 10.1 システムのコンセプト
  • 10.2 TODOアプリケーション
    • Webサーバ
    • リクエストハンドラ
    • テンプレート処理
    • 静的ファイルのサーブ
  • 10.3 リマインダメール送信
  • 10.4 Goにおけるフレームワーク
    • Gin
    • Echo
    • Micro
    • Beego
    • フレームワークの選定について
  • 10.5 まとめ

第11章 GitHubでの開発における勘所

  • 11.1 ライブラリの仕様
  • 11.2 プロジェクトの作成
  • 11.3 パッケージ名
  • 11.4 実装
  • 11.5 バージョニング
    • [COLUMN]GitHubのワンポイントTips
  • 11.6 テスト
  • 11.7 ドキュメント
    • go docの使い方
    • godocの使い方
    • https://pkg.go.dev/で閲覧する
  • 11.8 ディレクトリ構造
  • 11.9 自動テスト
  • 11.10 自動リリース
  • 11.11 まとめ

第12章 データベースの扱い方

  • 12.1 database/sql
    • サードパーティドライバ
    • Query/QueryRow
    • Exec
    • Prepare
    • Begin/Commit/Rollback
  • 12.2 ent/ent
    • OpenAPI連携
    • entgen
  • 12.3 ORMベンチマーク
  • 12.4 まとめ

第13章 Goとクラウドサービス

  • 13.1 Goがなぜ使われるのか
  • 13.2 Google Cloud
  • 13.3 AWS Lambda
  • 13.4 Oracle Cloud
    • [COLUMN]バイナリサイズを小さくする
  • 13.5 まとめ

サポート

正誤表

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

(2024年9月19日最終更新)

P.12 4行目

それ意外はlibcに依存しません。
それ以外はlibcに依存しません。

(以下2024年8月20日更新)

P.141 9行目

func body(b []byte) []byte {
func encodeBody(b []byte) []byte {

(以下2024年1月22日更新)

P.38 下から5行目

mapは順を持たないキーと値のペアです。
mapは順を持たないキーと値のペアです。

(以下2024年1月9日更新)

P.232 1行目

$ ./main -t 2022-11-26T08:23:05Z07:00
$ ./main -t 2022-11-26T08:23:05+09:00

(以下2023年12月13日更新)

P.45 本文4行目

underling type
underlying type

P.314 索引「U」の項目1つめ

underling type
underlying type

(以下2023年9月25日更新)

P.224  リスト9.19のキャプション

TestFindEntrieの変更個所
TestFindEntriesの変更個所

P.224  リスト9.20 のキャプション

最終的なTestFindEntrieの実装
最終的なTestFindEntriesの実装

(以下2023年4月10日更新)

P.57 本文2行目

「one two hree」
「one two three」

P.114

.
├── cmd
│     └── awesome
│         ├── awesome
│         └── main.go
.
├── cmd
│     └── awesome
│         └── main.go

※「cmd/awesome/awesome」が余計でした。

(以下2023年4月5日更新)

P.64 端末画面

$ go mod tidy -replace github.com/mattn/foobar=..
$ go mod tidy -replace github.com/mattn/foobar=../

P.64 リスト最終行

replace github.com/mattn/blahblah => ..
replace github.com/mattn/foobar => ../

P.64 本文6行目

examplesで使われているblahblahは、github.com/mattn/blahblahからではなく
examplesで使われているfoobarは、github.com/mattn/foobarからではなく

P.206 リスト9.1 15行目

InfoURL string
SiteURL string

P.209 リスト9.7 7行目

author := doc.Find("table[summary=作家データ] tr:nth-child(1) td:nth-child(2)").Text()
author := doc.Find("table[summary=作家データ] tr:nth-child(2) td:nth-child(2)").First().Text()

P.210 リスト9.8 8行目

author := doc.Find("table[summary=作家データ]:nth-child(1) tr:nth-child(2) td:nthchild(2)").Text()
author := doc.Find("table[summary=作家データ] tr:nth-child(2) td:nth-child(2)").First().Text()

※「nth-child(1) 」が余計でした。

P.228 リスト9.22 9行目

name := flag.String("name", "somthing", "my name")
name := flag.String("name", "something", "my name")

P.229 1つめの端末画面 6行目

my name (default "somthing")
my name (default "something")

P.229 本文5~6行目

time.Duratoinがあります。
time.Durationがあります。

P.250 2つめのリスト 8行目

t.user_id = u.id
t.id = u.id

(以下2023年3月30日更新)

P.212 8行目

findZipURLやfindEntriesを試験したくなった際には、
findAuthorAndZIPやfindEntriesを試験したくなった際には、

P.213 本文1行目

bytes.NewReaderを使ってZIPファイルを読み込みます。
zip.NewReaderを使ってZIPファイルを読み込みます。

P.221 表9.4 データベース照会プログラムの仕様

aozora-search artists
aozora-search authors

(以下2023年3月28日更新)

P.59 リスト3.12 下から13行目

for _, b := range ch {
for b := range ch {

※「_,」が余計でした。

P.150 リスト6.4 下から13行目

for _, b := range ch {
    r:=csv.NewReaderでbytes.NewReader(r))
for b := range ch {
    r:=csv.NewReaderでbytes.NewReader(b))

※「_,」が余計でした。

(以下2023年3月27日更新)

P.80 リスト4.5 9行目

func (i Fluit) String() string {
func (i Fruit) String() string {

P.81 本文3行目

fluit.go
fruit.go

P.81 本文4行目

Fluit
Fruit

P.153 リスト6.7 15行目

// fanIn is itself a generator
// fanInはそれ自体のジェネレータ

P.153 リスト6.7 16行目

// receives two read-only channels
// 2つの読み取り専用channelから読み取り

P.154 リスト6.7 12行目

// returns receive-only channel
// 受信専用channelを返す

P.154 リスト6.7 14行目

// anonymous goroutine
// 匿名関数goroutine

P.155 リスト6.8 12行目

// returns receive-only channel
// 受信専用channelを返す

P.155 リスト6.8 23行目

// anonymous goroutine
// 匿名関数goroutine

P.156 リスト6.9 11行目

// returns receive-only channel
// 受信専用channelを返す

P.156 リスト6.9 13行目

// anonymous goroutine
// 匿名関数goroutine

P.157 リスト6.10 13行目

// returns receive-only channel
// 受信専用channelを返す

P.157 リスト6.10 15行目

// anonymous goroutine
// 匿名関数goroutine

P.157 リスト6.10 19行目

// nothing
// 何もしない

P.158 リスト6.11 3行目

// returns receive-only channel
// 受信専用channelを返す

P.158 リスト6.11 5行目

// anonymous goroutine
// 匿名関数goroutine

P.158 リスト6.11 9行目

// nothing
// 何もしない

P.217 1つめのコード7行目

res, err = db.Exec(`INSERT INTO contents(author_id, title_id, title, content) values(?, ?, ?, ?)`,
    "000879",
    "14",
    "あばばばば",
    content,
)
if err != nil {
    log.Fatal(err)
}
res, err := db.Exec(`INSERT INTO authors(author_id, author) values(?, ?)`,
    "000879",
    "芥川竜之介",
)
if err != nil {
    log.Fatal(err)
}
res, err = db.Exec(`INSERT INTO contents(author_id, title_id, title, content) values(?, ?, ?, ?)`,
    "000879",
    "14",
    "あばばばば",
    content,
)
if err != nil {
    log.Fatal(err)
}

奥付ページ

https://gihyo.jp/book/2022/978-4-297-13419-8/support
https://gihyo.jp/book/2023/978-4-297-13419-8/support

(以下2023年3月22日更新)

本文全体

Goland
GoLand

P.15

Pythonで言うvenv
Pythonで言うpyenv

P.83 リスト4.7 24行目

type Data struct {
    Species string    `json:"species"`
    Description string    `json:"description"`
    Dimensions Dimensions    `json:"dimensions"`
}
type Data struct {
    Species string           `json:"species"`
    Description string       `json:"description"`
    Dimensions Dimensions    `json:"dimensions"`
}

※インデントがずれていました。

P.40 4つめのコード

type MyString stirng
type MyString string

(以下2023年3月20日更新)

P.167 リスト7.4 16行目

{name: "rhs is shorter than rhs", lhs: "fo", rhs: "foo", want: -1},
{name: "lhs is shorter than rhs", lhs: "fo", rhs: "foo", want: -1},

P.197 本文3行目

graphvis
graphviz

(以下2023年3月17日更新)

P.294 リスト12.8 8行目

err := db.Schema.Create(context.Background()
err := db.Schema.Create(context.Background())

(以下2023年3月14日更新)

P.39 3つめのコード5行目

fmt.Println(m) // map[Bob:2 John:1 Mark:3]が表示される
fmt.Println(m) // map[Bob:18 John:21 Mark:33]が表示される

P.84 3つめのコード

var data Data
dec := json.NewDecoder(f)
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
    line := scanner.Text()
    // 行ごとにJSONをデコード
    err := dec.Decode(&data)
    if err != nil {
        break
    }
    doSomething(&data)
}
var data Data
dec := json.NewDecoder(f)
for {
    err := dec.Decode(&data)
    if err != nil {
        break
    }
    doSomething(&data)
}

P.99 下から11行目

windowsかつ386
windowsまたは386

P.119 2行目

シュガーになっています
シンタックスシュガーになっています

P.234~235 端末画面

COMMANDS:
    list list students
    help, h Shows a list of commands or help for one command
COMMANDS:
    help, h Shows a list of commands or help for one command

※listからはじまる行が余計でした。

P.237 2つめの端末画面

"Go言語 好き太郎 golang@example.com>"
"Go言語 好き太郎 <golang@example.com>"

P.237 2つめのコード3行目

Go言語 好き太郎 golang@example.com>
Go言語 好き太郎 <golang@example.com>

(以下2023年3月13日更新)

P.42 1つめのコード2行目

user.wName
user.Name

「w」が余計でした。

P.89 1つめのコード5~6行目

if err != nil {
     log.Fatal(err) // 4m0s
}
fmt.Println(d)
if err != nil {
     log.Fatal(err)
}
fmt.Println(d) // 4m0s

P.168 7行目

Deve Cheney
Dave Cheney

P.205 1つめの端末画面下の注記

ご自身のGitHubに置き換え
ご自身のGitHubユーザ名に置き換え

P.274 本文2行目

Distanc
Distance

商品一覧