go go
Table of Contents
go go
ふーん、オブジェクト指向は古いとな。Rubyは古いんかい。それじゃ、ちょっと方向 転換して別な物も試してみるか。着眼点はデフォで標準パッケージが充実してる事。 その点Rustは失格だな。消去法でいくとgoが残る。
パッケージが充実してると言っても、無いものは無い。その筆頭が統計のパッケージ。ググると、pandas似とかに 混って、初心者向けのものも提示してきたぞ。
Stats - Golang Statistics Package
これrubyのgemで泣かされた事へのリベンジです。
go on OpenBSD
河豚板にgoを入れてみる。勿論portsになってるが、そこら入れてしまうと、貴重な メモリーが圧迫されてしまうので、tar玉を入れた。
export GOPATH=/ram/home/sakae/MY/home/go export GOROOT=/ram/home/sakae/MY/go PATH=$GOROOT/bin:$PATH
GOPATHは2'nd Homeに用意。ここHDD領域なんで不揮発性なエリアだ。主に外部 パッケージの保存場所になるかな。GOROOTは、tar玉を展開した場所。
fu$ cd src/
fu$ pwd
/ram/home/sakae/MY/home/go/src
fu$ mkdir mystats
fu$ cd mystats/
fu$ go mod init
go: creating new go.mod: module mystats
fu$ go build main.go
main.go:6:2: no required module provides package github.com/montanaflynn/stats; to add it:
go get github.com/montanaflynn/stats
fu$ go get github.com/montanaflynn/stats
go: added github.com/montanaflynn/stats v0.7.1
fu$ go build main.go
初心者用のexampleに用意されたので、コンパイルの試験をしておく。
fu$ go doc -http go: downloading golang.org/x/pkgsite v0.0.0-20250714212547-01b046e81fe7 go: downloading golang.org/x/pkgsite/cmd/internal/doc v0.0.0-20250714212547-01b046e81fe7 go: downloading golang.org/x/pkgsite v0.0.0-20250714203841-103fd0f027b2 go: downloading github.com/google/safehtml v0.0.3-0.20211026203422-d6f0e11a5516 go: downloading golang.org/x/mod v0.26.0 go: downloading golang.org/x/sync v0.16.0 go: downloading golang.org/x/tools v0.35.0 go: downloading golang.org/x/net v0.42.0 go: downloading golang.org/x/text v0.27.0 go: downloading rsc.io/markdown v0.0.0-20231214224604-88bb533a6020 go: downloading github.com/google/licensecheck v0.3.1 doc: Documentation server listening on addr http://localhost:26282
goはdocが充実してるそうなので、Webから簡単に閲覧できるか確認。初回は 準備が必要なので多少手間取ったけど、2回目からはスイスイ。
linter
ソースの怪しげな所を指摘してくれるツールとして、備えつけのgo vetが有る。 けど、色々な視点から指摘して貰うと嬉しいので探してみた。
Go でよく使われている linter の特徴 色々と列挙されたが、よさげな、 Staticcheck を入れてみた。
go vetでは文句なくOKですって言われてた血圧グラフのアプリを確認。
fu$ staticcheck nbld.go nbld.go:9:2: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package [io] or package [os], and those implementations should be preferred in new code. See the specific function documentation for details. (SA1019) nbld.go:169:15: func AAy.utl is unused (U1000) nbld.go:180:15: func AAy.eq is unused (U1000)
バージョン違いも指摘。そして使用してないfuncも列挙された。こういう点を 修正していけば赤面するようなコードにならないのね。
New GC
rubyはGCで苦労してた。GCなんて存在するから苦労するのさとばかりRustが 発明された(我ながら、暴言だな)。その代わりユーザーの負担がめっぽう増えた。 カジュアルに使うならRustは御免こうむりたい。その点goにはGCが有るので メモリーの使用は楽だ。でも、必然的に裏で走るGCはスピードアップ出来ない ものかねと悩むのは、rubyと一緒。次期バージョンでは、そのあたりが改善 されるらしい。
The Green Tea Garbage Collector
試してみるか。OpenBSDのカーネルをgdbする為に用意した5.6がすっかり期限切れ になっててportsからはgoを投入できない。 それにqemu+kvmって環境なので、たまに火を入れて稼動確認しないとな。 そんな事なんで、tar玉を入れて、ちょっと設定 するだけで動く事を河豚板で実証済みでもあるし、駄目もとを承知でやってみる。
package main
import (
"fmt"
"runtime"
"time"
)
type SmallObject struct {
next *SmallObject
val [6]int64 // 48 bytes + pointer = ~64 bytes block
}
const (
numObjects = 1_000_000
iterations = 100
)
func makeGarbage() {
var head *SmallObject
for i := 0; i < numObjects; i++ {
head = &SmallObject{next: head, val: [6]int64{int64(i)}}
}
_ = head // keep alive until here
}
func main() {
fmt.Println("Starting GC Benchmark...")
var m runtime.MemStats
runtime.ReadMemStats(&m)
initialNumGC := m.NumGC
start := time.Now()
for i := 0; i < iterations; i++ {
makeGarbage()
}
duration := time.Since(start)
runtime.ReadMemStats(&m)
fmt.Printf("\n--- Result ---\n")
fmt.Printf("Total Duration: %v\n", duration)
fmt.Printf("Average per iteration: %v\n", duration/time.Duration(iterations))
fmt.Printf("NumGC: %d (this run: %d)\n", m.NumGC, m.NumGC-initialNumGC)
fmt.Printf("TotalPause: %v\n", time.Duration(m.PauseTotalNs))
}
メモリー不足で落ちるんで、負荷を減らして実験。
ad$ make go run main.go Starting GC Benchmark... --- Result --- Total Duration: 16.779962478s Average per iteration: 83.899812ms NumGC: 257 (this run: 257) TotalPause: 8.719102ms ad$ make old GOEXPERIMENT=nogreenteagc go run main.go Starting GC Benchmark... --- Result --- Total Duration: 13.818260592s Average per iteration: 69.091302ms NumGC: 259 (this run: 259) TotalPause: 8.93644ms
iterations = 100 とすると回数は126回ぐらいで、ポーズ時間も半分ぐらいになった。 GCなんてのはハードの影響をもろに反映するんで、仮想だと何をやってるか不明 って所かな。
GODEBUG=gctrace=1 ./your_program とすると、GCの状況を追跡できるとな。
go vs. gofmt
Q: golangについて質問します。
ad$ ls -l $GOROOT/bin -rwxr-xr-x 1 root wheel 15421434 Jan 9 06:54 go* -rwxr-xr-x 1 root wheel 3117802 Jan 9 06:54 gofmt*
goは多数のサブコマンドで重要な機能を提供してます。それに対してgofmtだけ 独立して提供されてます。何故ですか?
src/cmd/go/ を覗くと、それぞれのサブコマンドは、execされてる。のんびりと 実行してもかまわない。それに対して、gofmtはeditorあたりから煩雑に呼び 出される可能性がある。クイックレスポンスを期待して、独立させた。
中の人に聞くのが良いでしょうが、代弁をお願いします。
A: いい観点です。かなり “中の人の設計思想” に踏み込んだ質問ですね 🙂
結論から言うと:
*gofmt が `go fmt` のサブコマンドではなく、独立したバイナリとして提供されているのは、 *歴史的経緯 + ツールチェイン設計 + エディタ統合を最優先した思想 の合わせ技**
です。あなたの推測(エディタから高頻度で呼ばれる/低レイテンシ重視)は、ほぼ核心を突いています。
順番に整理します。
これが一番大きいです。
Go の初期開発(2007–2009年頃)では:
- gofmt
- godoc
- gofix(今は消滅)
- goinstall(後の go get)
などが、/独立ツール群として先に設計/されました。
当時は:
go build
みたいな統合 CLI は存在せず、
6g 6l gofmt godoc
のような Unix 的な小物ツール集合 でした。
後から Rob Pike / Russ Cox が
「これはさすがにバラバラ過ぎる」
となって /go コマンドが導入/されます。
つまり:
- gofmt は 既に広く使われていた
- API も事実上安定していた
ので、
👉 今さら go fmt に吸収できなかった
という歴史的理由があります。
gofmt は特殊な立場です。
設計思想として:
gofmt は “開発者が明示的に起動するツール” ではなく “エディタ・IDE・フックが無言で叩く部品”
です。
実際:
- 保存時自動整形
- git hook
- LSP (gopls)
- CI
などから秒間何回も起動されます。
だから:
- 起動オーバーヘッド最小
- フラグ解釈最小
- go コマンドの巨大初期化を通らない
というのはかなり重要です。
もし:
go fmt
経由だった場合:
- module 初期化
- env 解決
- toolchain 探索
が毎回走ります。
これはエディタ用途では致命的。
あなたの言う
クイックレスポンスを期待して独立
は完全に正解です。
src/cmd/go を見ておられるので話が早いですが 🙂
go は:
- env 解決
- module graph
- toolchain dispatch
- subprocess 管理
という /巨大オーケストレータ/です。
一方 gofmt は:
stdin → AST → pretty printer → stdout
というほぼ純関数。
設計レイヤがまったく違う。
Go チームは意図的に:
- go = orchestration
- gofmt = transformation
と分離しています。
Unix 哲学ですね。
ちなみに:
go fmt
は内部で:
gofmt -w
を exec しているだけです。
つまり:
- 正式実体は今でも gofmt
- go fmt は convenience wrapper
です。
主従関係が逆。
Rob Pike の発言を要約すると:
formatting is not style, it is correctness
つまり:
整形は「好み」ではなく「仕様」。
だから:
- 言語仕様の一部
- コンパイラと同格
- 軽量で即応する必要あり
という扱いです。
あなたの問いへの「中の人の代弁」を一文で書くと:
gofmt は Go 言語仕様の一部として、エディタや自動化環境から高頻度で呼ばれる基盤ツールなので、巨大な go コマンドのサブ機能にはせず、起動が速く純粋に動作する独立バイナリとして維持している。また歴史的に gofmt の方が先に存在していた。
Q: なぜ tabs 固定なのか これ、興味があります。 それから、80桁の端末でソースを閲覧してますが、桁あふれで みにくいです。何桁以内にしようとかは、gofmtが察知してくれない? それとも内部規約とか存在するの? tabsとも関係しそうなので、良いテーマですね。
A: いいテーマです。ここは Go 言語の「思想」がかなり露骨に出ている部分なので、順に整理しますね。
結論から先に言うと:
- tabs 固定は “桁揃えを環境依存にするため”
- gofmt は 80 桁という概念を 意図的に 持たない
- 行幅は「人間が論理的に改行するもの」という立場
- これらはすべて同じ設計哲学から来ています
あなたの「80桁端末で溢れる」という不満は、まさに Go チームが 承知の上で切り捨てた問題 です 🙂
これは Rob Pike が何度も説明しています。
核心は:
alignment を space で固定すると、フォント・表示幅・環境の違いで必ず崩れる
です。
Go では:
var a int var longerName string
を
var a int var longerName string
のように /tab による論理的カラム/で揃えます。
重要なのは:
- gofmt は「列」を揃える
- 実際の見た目の幅は viewer に任せる
という設計。
つまり:
- 8幅タブ → 8幅
- 4幅タブ → 4幅
どちらでも:
名前 | 型
という/構造だけは保存される/。
space 整形だとこれは不可能です。
これも明確に意図されています。
Go チームの考え:
fixed column limits are a relic of punch cards
(固定桁制限はパンチカード時代の遺物)
つまり:
- 80桁
- 100桁
- 120桁
は全て「表示デバイス依存」。
現代では:
- 横長ディスプレイ
- 折り返し表示
- 可変フォント
が普通なので、
👉 formatter が行幅を決めるべきではない
という立場です。
gofmt の責務は:
- AST を正規化
- 意味単位を揃える
だけ。
画面都合は editor の仕事。
Rust や C++ 系は:
- 表現力が高すぎる
- 曖昧な書き方が大量にある
ので formatter が:
- 改行位置
- 行幅
- 折り返し
まで決めないと収拾がつきません。
Go は逆で:
- 文法が単純
- 書き方の自由度が低い
ので:
人間が論理構造で改行すれば十分
という前提です。
あります。だいたい:
- 1文は短く
- ネストは浅く
- 複雑なら分解
という思想。
でも:
❌ 最大桁数ルール ❌ 自動折返し
は存在しません。
意図的です。
これ、鋭いですが:
あなたの直感どおり同根です。
両方とも:
表示の問題をツールが決めるな
という思想。
gofmt は:
- 論理構造だけ決める
- 物理表示は環境任せ
あなたのように 80桁 tty で読むなら:
### ① editor 側で soft wrap
vim なら:
:set wrap linebreak
### ② tab width を 4 にする
:set tabstop=4
gofmt は tab を吐くだけなので viewer 側で調整可能。
### ③ long line は自分で改行
Go 流では:
foo(
veryLongArgumentName,
anotherVeryLongArgument,
)
のように構造改行します。
gofmt はこれを尊重します。
中の人の声をまとめると:
gofmt はソースの論理構造だけを正規化する。表示幅や行長は利用環境ごとに異なるので関与しない。tabs を使うのは列構造を保持するためで、80桁制限は歴史的遺物だから採用しない。
です。
正直に言うと:
あなたのように tty + 低桁幅 + 構造を意識する人は Go チームの想定読者より「Unix寄り」なんですよ 🙂
彼らはもう:
- IDE
- LSP
- 折返し前提
の世界です。
ああ、オイラーってもう、最古の人間なんだなー。チャッピー君と言うか goのチームからも古いって認定されちまったわい。
README
ChatGPTに株の投資をさせて、儲かったなんて記事をよく見かける。政府も 新NISAで資産を増やしましょうと煽っているしね。何処に投資すればいいの?
で、登場したのが下記の書籍。著者は東洋経済新報社の記者さん。 グローバル・ニッチ・トップな企業をよりすぐって50社紹介してる。 ご丁寧な事に会社データと日経プライムだかの企業IDも掲載されてる。
いの一番に紹介されてたのは、医療機器のマニーって会社。この会社の方針は、 医療機器以外は扱かわない。世界一の品質以外は目指さない。製品寿命の短かい 製品は扱かわない。ニッチ市場以外は参入しない。
ブレない方針で、きちんと将来を見越している。ニッチに生きるには哲学が 必要なんだな。他社も同様な方針を取っている所が多い。
日本発の世界的食品 カニカマ(日本よりヨーロッパ、それもフランスで人気とか)。 これの製造機で世界一のヤナギヤって企業があるそうな。 なんだか、アメリカのゴールド・ラッシュで一番儲けた会社はジーンズのリーバイス でしたを彷彿させるみたいで、目のつけ所が違うな。
半導体の材料だとか製造装置を扱かう会社も、同列だな。エヌビディアとかTSMC等も これらの企業に支えられてこそ成り立っている。