pblog

pplog.net を作っている @ppworks こと越川直人(Koshikawa Naoto)のブログ。文体は日によって違う。esa LLCで働いてます(\\( ⁰⊖⁰)/)

『スターティングGo言語』でGolang入門した

スターティングGo言語 (CodeZine BOOKS)

スターティングGo言語 (CodeZine BOOKS)

途中まで esa にメモりながら進めていたのでそのメモを投下しておく。 慣れてくると、実際にコード書いてみたり読んでなるほどという感じで進めていけたのでメモがなくなった。何より本自体がリファファレンスぽいのでメモが不要になったってのもある。

Golang をインストールする

https://github.com/syndbg/goenv を使ってみた。

git clone https://github.com/syndbg/goenv.git ~/.goenv

.zshrcなどにREADMEの内容を記述してから、

goenv install 1.10.3

:tada:

以下メモ。

いまは次の課題として、

Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る impress top gearシリーズ

Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る impress top gearシリーズ

を読みながらWEBアプリ作ってみるというのをやっている。なかなか面白い。『スターティングGo言語』とDocumentation - The Go Programming Languageを読みながら進めることが多い。


1. 開発環境

2. プログラムの構成と実行

  • go run hoge.goでビルドプロセスを隠蔽してコンパイルしたコードを実行できる
  • 参照のないパッケージをimportしたままだとコンパイルエラーとなる
    • _ "fmt"のように_を付けると、参照されていないパッケージを強制的にプログラム内に組み込むことができる
  • Goプログラムのエントリーポイントはmainパッケージの中に定義された関数mainであると定められている
  • go build -o hoge hoge.goでコンパイルして実行ファイルを作る

readelfコマンドがmacにないので、

brew install binutils

してgreadelfを入れてみる。

んがだめ

ELF ファイルではありません - 始点にあるマジック番号が異なります

https://teratail.com/questions/40401 Mac OS X上の実行可能バイナリはELF形式ではなく、Mach-O形式と呼ばれるフォーマットです。

そうなんすねー。linuxで試すかの。go動かせる環境をdockerで用意しよう。

docker pull golang

なるほどvimも入ってねえか。そりゃそう。

golangでdockerをはじめる ~ goのwebサーバーをdockerでたててみた ~ - Qiita

そうか、適当におれ用みたいなのをdocker hubにおいておきゃいいのね〜。

以下で遊べるようにしておいた。

docker container start golang_practice -ai

p.32 の 実行時に

go run main.go
package main:
main.go:3:8: expected 'STRING', found '{'
main.go:4:3: expected ';', found 'STRING' "fmt"

でハマった。import()なのね〜〜。エラーメッセージ的にもしかして()ってのは複数行でかく時用のもので、import String出かけるのかもと思って試したら、いけた。なるほどね!

git管理しておこうと思って、実行ファイルをどう除こうかな?と迷って調べた。

.gitignoreに拡張子なしのファイルを登録する - 備忘録置いとく

なるほど便利。

*
!*/
!*.*

3. 言語の基本

コメント

// コメント
/*
    コメント
*/

  • Goのコンパイラは{,で終わる場合を除いて、単純に分の終端であると判断し、;を自動で付与する。
    • じゃあなぜimportの中身はコンパイルエラーにならんのだ :thinking:
    • どうやらhoge ()()内に対してhogeをするのと同じことぽい(p. 57のvarの説明より)
a := [3]string{
    "A",
    "B", // ケツカンマが必須
}

定義済み識別子

https://golang.org/ref/spec#Predeclared_identifiers Types: bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr

Constants: true false iota

Zero value: nil

Functions: append cap close complex copy delete imag len make new panic print println real recover

変数

  • 値型, 参照型, ポイント型がある
var a1 int // 明示的宣言
var ( // 複数同時宣言
    a2, a3 int = 2, 3
    a4     string
)
a4 := 4 // 定義と代入をまとめて暗黙的に型を定義

基本型

  • rune型
    • ''で囲う
    • Unicodeコードポイントを表す特殊な整数型
    • int32の別名なので中身は整数と全く同じ
  • 文字列型
    • ""で囲う
  • RAW文字列リテラル
    • ``で囲う
    • \nなどもそのまま表示される、改行入れたければ実際に改行する
runeType := '越' // シングルクォーテーションはrune型となる
var int32Type int32 = '越'

// 36234 == 36234 // true
fmt.Printf("%v == %v // %v\n", runeType, int32Type, runeType == int32Type) 

s := "越川"
ss := `文字列
たくさんかくよ〜
へいへい`

fmt.Printf("%v said: %v\n", s, ss)

配列型

  • 固定長
  • 可変長は、スライスという型がある
b1 := [3]int{1, 2, 3}
b2 := [...]int{1, 2, 3} // 要素数の省略

interface()

  • Goにおけるあらゆる型と互換性のある特殊な型
    • 値が入っていないときには、nilになる
    • すべての型の値を汎用的に表す手段
    • 演算の対象にはできない

関数

error 処理のイディオム

package main

import (
    "errors"
    "fmt"
)

func doSomething() (bool, error) {
    error := errors.New("Something error")
    return true, error
}

func main() {
    result, error := doSomething()
    if error != nil {
        // error 処理
        fmt.Printf("error: %v\n", error)
    }
    fmt.Printf("result: %v\n", result)
}

定数

  • 整数値の定数には原則として最大値がない
    • 整数値の定数と基本型の整数値は根本的に別のもの
const (
    A = iota // const中で定数が定義されるたびに増えるので 0
    B = iota // const中で定数が定義されるたびに増えるので 1
    C = iota // const中で定数が定義されるたびに増えるので 2
    D = "D"  // const中で定数が定義されるたびに増えるが使わない
    E = iota // const中で定数が定義されるたびに増えるので 4
)

const (
    X = iota
    Y
    Z
)

スコープ

  • パッケージ
  • ファイル
    • import 宣言のみ独立している
  • 関数
  • ブロック
  • 制御構文(if, forなど)

for

for {
    break // 無限ループ
}

for i := 0; i < 10; i++ {
    fmt.Printf("i: %v ", i)
    fmt.Println()
}

// Range Clause による for
for i, v := range [3]string{"上々家", "誠家", "雷家"} {
    fmt.Printf("ramens[%v] = %v\n", i, v)
}

if

if _, err := doSomething(); err != nil {
    // err は ifの中だけで参照されるスコープ
}

フォーマット整形してくれる便利ツール

脇道それるけど、gitのhookってどう管理するのがベストかなーと調べて見た。

https://github.com/git-hooks/git-hooks

昔こういうの見たことある気もするが使ってなかったな。


というところで、メモは終わっている。理由は、冒頭で説明した通り。

スターティングGo言語 (CodeZine BOOKS)

スターティングGo言語 (CodeZine BOOKS)

フィードバック(追記)