2021/12/20

golangの本を買いにいったが止めた

golang をネットで場当たり的に調べるのも良いが、本を買ってじっくり学ぶというのもやりたい。
私はまだ技術書をデジタル書籍ではうまく扱えないので、本屋さんに行ってきた。

紀伊國屋と丸善を回ったのだが、どちらも同じような状況だった。
買わずに家に帰って調べたのだが(買いに行く前にやれってね)、本屋さんにあったような本しかなかった。

 

入門書でも良いのだけど、インストールの仕方とかツールの使い方とかに比重が置かれているタイプではなく、サーバプログラミングに重点を置いているようなものでもなく、言語仕様に重点が置かれている本が買いたかったのだ。

となると、これしか出てこない。

プログラミング言語Go - 丸善出版 理工・医学・人文社会科学の専門書出版社
https://www.maruzen-publishing.co.jp/item/?book_no=295039

本屋さんにもあったのに買い控えたのは、これが2016年出版と5年前だからだ。オリジナルは2015年。
電子書籍版も2021年5月に出ているのだが、内容が更新されたわけではないだろう。
C言語だと多少古くてもなんとかなると思うのだが、Go言語は最近の言語。
6, 7年も前だと変更がいろいろ行われていそうで止めたのだ。

候補になりそうなのはオライリーさんのだけど、これはまだ日本語になってない。

Learning Go [Book]
https://www.oreilly.com/library/view/learning-go/9781492077206/

というわけで、買うのを止めたのだった。


しかし家に帰ってよく考えたのだが、ツールの使い勝手が変わっても言語自体は変わってないのかも・・・?
そこを調べておくべきだろう。

  • v1.1
    • integer division by zero
    • surrogates in Unicode literals
    • method values
    • return requirements
  • v1.2
    • use of nil
    • three-index slices
  • v1.3
    • 無しなのかな?
  • v1.4
    • for-range loops
    • method calls on **T
  • v1.5
    • map literals
  • v1.6
    • 無し
  • v1.7
    • terminating statements
  • v1.8
    • explicit converting
  • v1.9
    • type aliases
    • 浮動小数点演算の丸め関係
  • v1.10
    • 一応無し
  • v1.11
    • 無し
  • v1.12
    • 無し
  • v1.13
    • リテラルのプレフィクス追加(0b, 0o など)
    • ビットシフト量を unsigned に変更
  • v1.14
    • overlapping interfaces proposal
  • v1.15
    • 無し
  • v1.16
    • 無し
  • v1.17
    • conversions from slice to array pointer
    • unsafe.Add()
    • unsafe.Slice()
  • v1.18
    • これを書いている時点では未定
    • 404 は "to, err := human()" なのね

あまり読まずに抜き出したので、間違いがあったら済まぬ。

 

 

オリジナル本の "The Go Programming Lanuguage" は、どうも v1.5 の時代に書かれているようだ(Contents の PDFより)。

v1.6 以降で気になる変更点は、type alias のサポートとか interface関係かなぁ。
しかし標準ライブラリへの変更や追加もあるだろうから、やっぱり悩むな。。。

2021/12/19

[golang]go.mod の require にリリースバージョンを付けたい

以前、go.mod で特定の commit-id を指定するやり方を調べた。

hiro99ma blog: [golang] go.mod の pseudo-version
https://blog.hirokuma.work/2021/12/golang-gomod-pseudo-version.html

が、よく考えれば普通は pseudo じゃないバージョンを使っているのだ。
そのバージョンの指定方法を調べておくべきだろう。

https://go.dev/doc/modules/gomod-ref#require

require の文法は

require module-path module-version

で、リリースバージョンか pseudoバージョンとのこと。

リリースバージョンってなんじゃ?
git tag でよいのか?

前回の gogo-test4 に v0.1.0 のタグを付けて push。
GitHub のリリースにはしていないが、tags には出てくる。

https://github.com/hirokuma/gogo-test4/tags

で、これを require している gogo-test3 で指定する。

https://github.com/hirokuma/gogo-test3/blob/66a97f39163f91ab9bd945a1c45ff80de37a6d7d/go.mod#L5

go mod tidy してもエラーにならないから、これでよいようだ。

ただ、git tag って push した後でも消したり差し替えたりできると思うので安心しきってはいかんのかもしれんな。

[golang]ライブラリが持つグローバル変数

グローバル変数と呼んでよいのかどうかわからんが、パッケージ内に変数を置けばグローバル変数みたいな扱いができると思う。
小文字だとパッケージ外からはアクセスできないが、ローカル変数かグローバル変数かでいえばグローバル変数だからどこからアクセスしても本体は同じだ。

 

さて、ではこれがライブラリだったらどういう扱いになるのだろうか?
もし1箇所でしか使っていないなら気にしなくてよいと思うが、複数のパッケージで同じライブラリを import していたら、それは別のメモリとして扱われるのか、同じメモリとして扱われるのか。

https://github.com/hirokuma/gogo-test3

https://github.com/hirokuma/gogo-test4

gogo-test3 の中にパッケージ gogo1 と gogo2 があって、それぞれグローバル変数(パッケージ変数、の方が良いのか?)を置いている。
そしてそれぞれが gogo-test4 を import している。

gogo-test4 はグローバル変数がある。

gogo-test3 の main() で、gogo1 の中で gogo1 と gogo-test4 を更新 → gogo2 の中で gogo2 と gogo-test4 を更新 → gogo1 側の gogo-test4 の値を見てみる、ということをやっている。
結果はこうなる。 2つ数値が出力されるうち、前者が package 内のグローバル変数、後者が gogo-test4 のグローバル変数である。

$ go run .
gogo1 10, 10
gogo2 20, 20
gogo1 10, 20

gogo2 で設定した gogo-test4 の値が gogo1 の方でも取得されているので、取りあえずこういうシンプルな書き方であれば import を複数の箇所で行っていても 1つのものだと判定されるようだ。
New 関数を package が持っていることが多いのは、動的に変数を用意しないと知らないところからアクセスされて値が書き換わっていた、なんてことが起きてしまうのを防ぐためだ。
あるいは、どこからアクセスしても同じデータを使いたいなら、あえてそう作ればよいということだ。

2021/12/05

[golang] go.mod の pseudo-version

hiro99ma blog: [golang] go.mod の pseudo-version の調べ方がわからん
https://blog.hirokuma.work/2021/11/golang-gomod-pseudo-version.html

git log を加工したらよいのではなかろうか、ということでこうなった。

TZ=UTC git log -n1 --abbrev-commit --abbrev=12 --date=format-local:%Y%m%d%H%M%S

 

たとえばここだとこうなる。

$ TZ=UTC git log -n1  --abbrev-commit --abbrev=12 --date=format-local:%Y%m%d%H%M%S
commit 382e4677bbfb (HEAD -> main, tag: v3, origin/main, origin/HEAD)
Author: hirokuma <hiro9ma@gmail.com>
Date:   20211121014212

    v3

最初は時間がJSTになってて、go mod tidyするとタイムスタンプが違うといわれてしまった。
かといってどうやって UTC にするんじゃ?ってなって。TZ 設定したけど --date=format: にしていたので反映されずに悩んでしまった。

metadata - Git: show dates in UTC - Stack Overflow
https://stackoverflow.com/questions/21363187/git-show-dates-in-utc

 

先頭の 1つだけしか出力しないのだが、私の使い方だとそれで十分だ。

が、ちょっと欲が出るよね?
もうちょっと go.mod 風の出力にならんだろうかと。

$ TZ=UTC git log -n1  --abbrev-commit --abbrev=12 --date=format-local:%Y%m%d%H%M%S --format=format:%ad-%h
20211121014212-382e4677bbfb

コマンドラインが長いのだけど、どうせ記憶できる長さじゃないので alias にでも設定しておけばいいや。