新機能
go/token パッケージの File 型に、ファイル名と位置範囲を含む簡潔な説明を返す String メソッドを追加した。
go/token
この項目の注釈は AI により生成されており、誤りを含む場合があります。
使用例のコンパイル検証: 検証済み
概要
go/token パッケージの File 型に fmt.Stringer を実装する String メソッドが追加された。これまで *File を fmt.Println 等でそのまま出力すると、非公開フィールドを含む構造体の生ダンプ(大規模ファイルでは巨大な行オフセットテーブルまで含む)が表示されてしまっていたが、今後はファイル名と位置範囲(Base〜End)からなる簡潔な説明が得られるようになる。
導入経緯
提案者の @adonovan は、Issue #76285 で token.NewFileSet().AddFile(...) の結果を fmt.Println した際に内部構造がそのままダンプされてしまう問題を指摘し、String メソッドの追加を提案した。当初はファイル名のみを返す案だったが、レビューで「Name() を直接呼べばよいのでは」という指摘を受け、位置範囲(Base〜End)も含む "%s(%d-%d)" 形式に改められた。関連する Issue #75849((*File).End() メソッドの追加)が先行して実装されており、本提案の String はその End() を利用している。
議論タイムライン
- 2026-02-09: 提案レビュー会議で "likely accept" と判断された(週次ダイジェスト記事)。
- 2026-02-18: 反対意見がなかったため正式に "accepted" となった(週次ダイジェスト記事)。
議論のハイライト
Stringの出力内容について、当初案の「ファイル名のみ」に対し、レビュアーから「ファイル名だけならName()を直接呼べばよい」との指摘があり、より情報量の多いフォーマットへ改められた。- 出力フォーマットをどこまで詳細にすべきかという議論もあったが、最終的には「人間が読める簡潔な説明」とし、実装の細部は実装者の裁量に委ねる方向で収束した。
fmt.GoStringer(%#v用)を別途実装する案も出たが、本提案では採用されなかった。
使用例
Before
package main
import (
"fmt"
"go/token"
)
func main() {
fset := token.NewFileSet()
f := fset.AddFile("foo.go", -1, 100)
fmt.Println(f)
// 出力: &{foo.go 1 100 {{} {0 0}} [0] []}
}
After
package main
import (
"fmt"
"go/token"
)
func main() {
fset := token.NewFileSet()
f := fset.AddFile("foo.go", -1, 100)
fmt.Println(f)
// 出力: foo.go(1-101)
}
実装解説
実装(go/token/position.go)は次の通りで、提案時のコードのまま採用されている。
func (f *File) String() string {
return fmt.Sprintf("%s(%d-%d)", f.Name(), f.Base(), f.End())
}
Name()・Base()・End() はいずれも既存の公開メソッドで、End() は関連提案 #75849 で追加されたものを利用している。新たな状態やフィールドは持たず、既存の情報を組み合わせて文字列化するだけの薄いメソッドである。