A Tour of Go やってみた
直近しばらくJavaマンだったが、golangの機運が高まってきたので、
をやってみる
Hello, 世界
Macのセットアップは以下を参照
リポジトリは以下、
% go version
go version go1.23.4 darwin/arm64
ん?
% go tool tour
go: no such tool "tour"
英語版のコマンドを見てみるといいらしい。
% go install golang.org/x/website/tour@latest
go: downloading golang.org/x/website/tour v0.0.0-20210616181959-e0d934b43647
go: downloading golang.org/x/website v0.0.0-20241223144644-abd320122603
go: downloading golang.org/x/tools v0.1.3-0.20210525215409-a3eb095d6aee
go: downloading golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
go: downloading golang.org/x/mod v0.4.2
go: downloading golang.org/x/sys v0.0.0-20210510120138-977fb7262007
go: downloading github.com/yuin/goldmark v1.3.5
go: downloading golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
んーよくわからないけど、進めてみる。
% ~/go/bin/tour
2024/12/26 16:03:19 Serving content from /Users/kazukichi/go/pkg/mod/golang.org/x/website/tour@v0.0.0-20210616181959-e0d934b43647
2024/12/26 16:03:19 A browser window should open. If not, please visit http://127.0.0.1:3999
2024/12/26 16:03:19 accepting connection from: 127.0.0.1:62193
が立ち上がってローカルでA Tour of Goが出来るみたい。
ローカルで普通に開発できるのかと思ったけど、思ってたんと違ったw
蛇足)
ひとまずhello.goを作って動かしてみる。
VSCodeのextentionも追加。
% go run 1-Welcome/hello.go
Hello, 世界
% go run 1-Welcome/sandbox.go
Welcome to the playground!
The time is 2024-12-26 16:17:31.793507 +0900 JST m=+0.000168168
OK
Packages
% go run 2-Packages-variables-and-functions/packages.go
My favorite number is 2
% go run 2-Packages-variables-and-functions/packages.go
My favorite number is 1
% go run 2-Packages-variables-and-functions/packages.go
My favorite number is 9
Note: ここで実行するプログラムは常に同じ環境で実行されます ので、擬似乱数を返す rand.Intn はいつも同じ数を返します。
(数を強制的に変える場合は、乱数生成でシードを与える必要があります。rand.Seedを見てみてください。 playground 上での時間は一定なので他のものをシードとして使う必要があります。)
ここがよくわからない・・
ローカルでもweb上でもちゃんと乱数生成できてるけどな。。
英語版にはそのような表記なし。
もしかして日本語版、結構怪しい感じ??
Imports
importはまとめるのがお作法。
% go run 2-Packages-variables-and-functions/imports.go
Now you have 2.6457513110645907 problems.
平方根を求めるやつ
Exported names
% go run 2-Packages-variables-and-functions/exported-names.go
# command-line-arguments
2-Packages-variables-and-functions/exported-names.go:8:14: undefined: math
Piに変える。
% go run 2-Packages-variables-and-functions/exported-names.go
3.141592653589793
Piって円周率か。
const.goに定数定義されてた
// Mathematical constants.
const (
E = 2.71828182845904523536028747135266249775724709369995957496696763 // https://oeis.org/A001113
Pi = 3.14159265358979323846264338327950288419716939937510582097494459 // https://oeis.org/A000796
Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // https://oeis.org/A001622
Sqrt2 = 1.41421356237309504880168872420969807856967187537694807317667974 // https://oeis.org/A002193
SqrtE = 1.64872127070012814684865078781416357165377610071014801157507931 // https://oeis.org/A019774
SqrtPi = 1.77245385090551602729816748334114518279754945612238712821380779 // https://oeis.org/A002161
SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // https://oeis.org/A139339
Ln2 = 0.693147180559945309417232121458176568075500134360255254120680009 // https://oeis.org/A002162
Log2E = 1 / Ln2
Ln10 = 2.30258509299404568401799145468436420760110148862877297603332790 // https://oeis.org/A002392
Log10E = 1 / Ln10
)
Functions
型定義は後ろ。
% go run 2-Packages-variables-and-functions/functions.go
55
構文に込められた思い
ポインタがあるのか。C++以来でドキドキ。
Functions continued
同じ型の変数は省略可能。
Multiple results
標準で複数returnできるのアツい!
(javaだと自前で入れ物作るか、Pairとか使わないといけなかった・・)
% go run 2-Packages-variables-and-functions/multiple-results.go
world hello
Named return values
関数定義でreturn 対象変数を宣言することができる、が、多用すると可読性落ちると。
% go run 2-Packages-variables-and-functions/named-results.go
7 10
Variables
変数宣言。一応調べたけど、valは存在しないと。
final もないっぽいけど、もしや再代入防ぐのちょいめんどい??
% go run 2-Packages-variables-and-functions/variables.go
0 false false false
基本final付けたいマン、基本immutableにしたいマンなので、ちょっと調べてみたら、
以下が参考になった。
イミュータブル修飾が効率的に機能するには関数型言語としての最適化機能もなければ片手落ち
くっ・・耳が痛い。。
Variables with initializers
var c, python, java = true, false, "no!"
んー、これは慣れないと読みづらいw
% go run 2-Packages-variables-and-functions/variables-with-initializers.go
1 2 true false no!
Short variable declarations
var は := で代替可能。
1文字しか減ってない気もするけど・・
プロジェクト毎にどっちで定義するってコーディング規約は作られる感じかな
% go run 2-Packages-variables-and-functions/short-variable-declarations.go
1 2 3 true false no!
Basic types
基本型(組み込み型)について。
import同様、varもまとめて宣言可能。
「<<」「>>」はビット演算子。(いきなり出すのズルない?w)
complexは複素数。
複素数の平方根ってことでいいのかな。なんか例がムズいんだがw
% go run 2-Packages-variables-and-functions/basic-types.go
Type: bool Value: false
Type: uint64 Value: 18446744073709551615
Type: complex128 Value: (2+3i)
%Tでtype出力できるのいいね
Zero values
暗黙の初期値。
特に違和感ないけど、書式指定子がわからんので調べる。
https://qiita.com/ken/items/2c0cc33bb8edf8b8160f
% go run 2-Packages-variables-and-functions/zero.go
0 0 false ""
Type conversions
暗黙のキャストはない。
% go run 2-Packages-variables-and-functions/type-conversions.go
3 4 5
明示的に書かなければエラー。
% go run 2-Packages-variables-and-functions/type-conversions.go
# command-line-arguments
2-Packages-variables-and-functions/type-conversions.go:12:15: cannot use f (variable of type float64) as uint value in variable declaration
Type inference
右辺に合わせて型推論してくれる。
% go run 2-Packages-variables-and-functions/type-inference.go
v is of type int
i := 42 // int
f := 3.142 // float64
g := 0.867 + 0.5i // complex128
Constants
定数定義。
% go run 2-Packages-variables-and-functions/constants.go
Hello 世界
Happy 3.14 Day
Go rules? true
定数は、文字(character)、文字列(string)、boolean、数値(numeric)のみ
Numeric Constants
constも型省略可能で、変数同様に推論される。
% go run 2-Packages-variables-and-functions/numeric-constants.go
21
0.2
1.2676506002282295e+29
For
% go run 3-Flow-control-statements/for.go
45
For continued
% go run 3-Flow-control-statements/for-continued.go
1
2
4
8
16
32
64
128
256
512
1024
For is Go's "while"
whileと同じように書ける
Forever
条件を書かなければ無限ループになる
If
% go run 3-Flow-control-statements/if.go
1.4142135623730951 2i
If with a short statement
Powはべき乗
% go run 3-Flow-control-statements/if-with-a-short-statement.go
9 20
If and else
% go run 3-Flow-control-statements/if-and-else.go
27 >= 20
9 20
Exercise: Loops and Functions
copilot有効のままになってて、一瞬で答え書かれた・・
% go run 3-Flow-control-statements/exercise-loops-and-functions.go
1.4142135623730951
Switch
% go run 3-Flow-control-statements/switch.go
Go runs on OS X.
Switch evaluation order
% go run 3-Flow-control-statements/switch-evaluation-order.go
When's Saturday?
Today.
Switch with no condition
なんこれ、オシャレじゃん・・
% go run 3-Flow-control-statements/switch-with-no-condition.go
Good afternoon.
Defer
急にちょっとクセあるやつキタ・・
実際の業務でどのくらい使われるのか気になる。。
% go run 3-Flow-control-statements/defer.go
hello
world
Stacking defers
LIFOなのか!
try-with-resourcesみたいなものはなくて、これ使う感じかな。
% go run 3-Flow-control-statements/defer-multi.go
counting
done
9
8
7
6
5
4
3
2
1
0
Pointers
% go run 4-More-types/pointers.go
42
21
73
Structs
% go run 4-More-types/structs.go
{1 2}
Struct Fields
% go run 4-More-types/struct-fields.go
4
Pointers to structs
% go run 4-More-types/struct-pointers.go
{1000000000 2}
Struct Literals
% go run 4-More-types/struct-literals.go
{1 2} &{1 2} {1 0} {0 0}
Arrays
% go run 4-More-types/array.go
Hello World
[Hello World]
[2 3 5 7 11 13]
Slices
% go run 4-More-types/slices.go
[3 5 7]
Slices are like references to arrays
スライスは配列への参照のようなもの
% go run 4-More-types/slices-pointers.go
[John Paul George Ringo]
[John Paul] [Paul George]
[John XXX] [XXX George]
[John XXX George Ringo]
Slice literals
% go run 4-More-types/slice-literals.go
[2 3 5 7 11 13]
[true false true true false true]
[{2 true} {3 false} {5 true} {7 true} {11 false} {13 true}]
Slice defaults
% go run 4-More-types/slice-bounds.go
[3 5 7]
[3 5]
[5]
Slice length and capacity
% go run 4-More-types/slice-len-cap.go
len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]
え、、急にむずい・・w
参考:
Nil slices
% go run 4-More-types/nil-slices.go
[] 0 0
nil!
Creating a slice with make
% go run 4-More-types/making-slices.go
a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0]
d len=3 cap=3 [0 0 0]
Slices of slices
% go run 4-More-types/slices-of-slice.go
X _ X
O _ X
_ _ O
Appending to a slice
% go run 4-More-types/append.go
len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]
Range
% go run 4-More-types/range.go
2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
Range continued
% go run 4-More-types/range-continued.go
1
2
4
8
16
32
64
128
256
512
Exercise: Slices
% go run 4-More-types/exercise/exercise-slices.go
4-More-types/exercise/exercise-slices.go:3:8: no required module provides package golang.org/x/tour/pic: go.mod file not found in current directory or any parent directory; see 'go help modules'
import "golang.org/x/tour/pic"
がうまく取れていない模様。
公式:
解説助かる。
モジュール初期化
% go mod init exercise
go: creating new go.mod: module exercise
go: to add module requirements and sums:
go mod tidy
再度実行。
% go run exercise-slices.go
exercise-slices.go:3:8: no required module provides package golang.org/x/tour/pic; to add it:
go get golang.org/x/tour/pic
言われるがまま。
% go get golang.org/x/tour/pic
go: downloading golang.org/x/tour v0.1.0
go: added golang.org/x/tour v0.1.0
go.sumファイルができたみたい
% go run exercise-slices.go
# command-line-arguments
./exercise-slices.go:7:1: missing return
importのエラーは解消した模様。
% go run exercise-slices.go
IMAGE:iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACaUlEQVR42uzVMRGAAAzAwLSHf8tgAAf95QVkyVNvNRN50FWBl10V6ABa0AFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIB6ADqEAHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdAA6gBZ0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIB6AAq0AFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgA6gAh2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADyxy8AAP//YSoDD5pLB7MAAAAASUVORK5CYII=
ターミナルで実行してもイマイチなので、ここはサイト上で実行しました。
青い画像が色々と作れる
Maps
% go run 4-More-types/maps.go
{40.68433 -74.39967}
Map literals
% go run 4-More-types/map-literals.go
map[Bell Labs:{40.68433 -74.39967} Google:{37.42202 -122.08408}]
Map literals continued
% go run 4-More-types/map-literals-continued.go
map[Bell Labs:{40.68433 -74.39967} Google:{37.42202 -122.08408}]
Mutating Maps
% go run 4-More-types/mutating-maps.go
The value: 42
The value: 48
The value: 0
The value: 0 Present? false
Exercise: Maps
% go run exercise-maps.go
PASS
f("I am learning Go!") =
map[string]int{"Go!":1, "I":1, "am":1, "learning":1}
PASS
f("The quick brown fox jumped over the lazy dog.") =
map[string]int{"The":1, "brown":1, "dog.":1, "fox":1, "jumped":1, "lazy":1, "over":1, "quick":1, "the":1}
PASS
f("I ate a donut. Then I ate another donut.") =
map[string]int{"I":2, "Then":1, "a":1, "another":1, "ate":2, "donut.":2}
PASS
f("A man a plan a canal panama.") =
map[string]int{"A":1, "a":2, "canal":1, "man":1, "panama.":1, "plan":1}
Function values
% go run 4-More-types/function-values.go
13
5
81
Function closures
% go run 4-More-types/function-closures.go
0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90
んーめっちゃ違和感。
この辺を読んでいたらだいぶ腹落ちしてきた。
ところどころまだ出てきてない概念があるので、後で読み直す。
Exercise: Fibonacci closure
% go run 4-More-types/exercise/exercise-fibonacci-closure.go
0
1
1
2
3
5
8
13
21
34