[インデックス 17452] ファイルの概要
このコミットは、Go言語の標準ライブラリ net
パッケージ内の lookup.go
ファイルに対する変更です。主な目的は、コードの可読性と整理を向上させるために、IPアドレスのルックアップに関連する関数群を論理的にまとめること、およびインポート宣言の記述スタイルを統一することです。
コミット
commit 29de03adf38a1a813500e3fa2953740282b9a1e5
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Sat Aug 31 16:29:50 2013 +0900
net: keep lookup IP stuff close
Also flattens import declaration.
R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/13373046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/29de03adf38a1a813500e3fa2953740282b9a1e5
元コミット内容
net: keep lookup IP stuff close
Also flattens import declaration.
変更の背景
このコミットは、Go言語の標準ライブラリ net
パッケージのコードベースの保守性と可読性を向上させることを目的としています。具体的な背景としては、以下の点が挙げられます。
- コードの局所性(Locality)の向上:
LookupHost
とLookupIP
という、ホスト名やIPアドレスのルックアップに関連する公開関数が、ファイル内の異なる場所に散らばっていました。これらの関数を関連性の高い他の変数(protocols
マップやlookupGroup
)の近くに配置することで、コードを読む人が関連する定義やロジックを一度に見つけやすくなります。これは、コードの理解を深め、将来的な変更やデバッグを容易にする上で重要です。 - インポート宣言の統一: Goのコードスタイルガイドラインでは、単一のパッケージをインポートする場合、
import "package"
の形式を推奨しています。このコミット以前は、time
パッケージのインポートが複数行のブロック形式で記述されていましたが、これを単一行形式に修正することで、コードベース全体のスタイルの一貫性を保ち、Goの慣習に沿った記述にしています。 - リファクタリングの一環: このような変更は、機能追加やバグ修正とは異なり、既存のコードの構造を改善する「リファクタリング」の一環として行われます。リファクタリングは、長期的なソフトウェア品質を維持するために不可欠な活動です。
前提知識の解説
このコミットを理解するためには、以下のGo言語およびネットワークに関する基本的な知識が役立ちます。
- Go言語のパッケージとインポート: Go言語では、関連する機能は「パッケージ」としてまとめられます。他のパッケージの機能を利用するには、
import
キーワードを使ってそのパッケージをインポートする必要があります。インポート宣言には、複数行で複数のパッケージをインポートする形式と、単一行で一つのパッケージをインポートする形式があります。Goの慣習として、単一インポートの場合は単一行形式が好まれます。 net
パッケージ: Goの標準ライブラリの一部であり、ネットワークI/Oのプリミティブインターフェースを提供します。TCP/IP、UDP、DNSルックアップなど、様々なネットワーク関連の機能が含まれています。- DNSルックアップ: ドメイン名(例:
google.com
)をIPアドレス(例:172.217.160.142
)に変換するプロセスです。LookupHost
やLookupIP
といった関数は、このDNSルックアップを実行するために使用されます。 singleflight
パッケージ(概念): Goの標準ライブラリには直接singleflight
というパッケージは存在しませんが、golang.org/x/sync/singleflight
パッケージとして提供されています。これは、複数のゴルーチンが同じキーで同じ関数を呼び出そうとしたときに、その関数が実際に実行されるのは一度だけで、すべての呼び出し元にその結果を共有させるためのメカニズムです。これにより、重複する作業を防ぎ、リソースの消費を抑えることができます。lookupGroup singleflight
という変数名から、このコミットの対象ファイルでも同様のパターンが使われていることが示唆されます。DNSルックアップのような操作は、同じホスト名に対して何度も実行される可能性があるため、singleflight
パターンは非常に有効です。
技術的詳細
このコミットは、src/pkg/net/lookup.go
ファイルに対して行われました。このファイルは、主にDNSルックアップやポートルックアップといった、ネットワークアドレス解決に関する機能を提供しています。
変更の技術的な詳細は以下の通りです。
-
インポート宣言の変更:
- 変更前:
import ( "time" )
- 変更後:
import "time"
これは、Goのツール
goimports
やgofmt
が推奨するスタイルに合わせたもので、コードの自動整形ツールとの整合性を高めます。機能的な変更は一切ありません。 - 変更前:
-
LookupHost
およびLookupIP
関数の移動:- 変更前は、
LookupHost
関数はlookupIPMerge
の後に、LookupIP
関数はlookupIPDeadline
の後に定義されていました。 - 変更後は、これらの関数が
protocols
マップとlookupGroup
変数の直後に移動されました。protocols
は、プロトコル名と番号のマッピングを定義しています。lookupGroup
は、singleflight
パターンを実装するための変数で、重複するルックアップリクエストをまとめる役割を担っています。 この移動により、LookupHost
とLookupIP
が、それらが利用する内部的なメカニズム(lookupGroup
を介した重複排除など)や関連データ(protocols
)の近くに配置され、コードの論理的なまとまりが強化されました。
- 変更前は、
これらの変更は、Goのコードベース全体で一貫したスタイルと構造を維持するための継続的な取り組みの一部です。機能的な振る舞いは一切変更されていませんが、将来のメンテナンスや新規開発において、開発者がコードをより迅速に理解し、変更を加えることを容易にします。
コアとなるコードの変更箇所
--- a/src/pkg/net/lookup.go
+++ b/src/pkg/net/lookup.go
@@ -4,9 +4,7 @@
package net
-import (
- "time"
-)
+import "time"
// protocols contains minimal mappings between internet protocol
// names and numbers for platforms that don't have a complete list of
@@ -21,6 +19,18 @@ var protocols = map[string]int{
"ipv6-icmp": 58, "IPV6-ICMP": 58, "IPv6-ICMP": 58,
}
+// LookupHost looks up the given host using the local resolver.
+// It returns an array of that host's addresses.
+func LookupHost(host string) (addrs []string, err error) {
+ return lookupHost(host)
+}
+
+// LookupIP looks up host using the local resolver.
+// It returns an array of that host's IPv4 and IPv6 addresses.
+func LookupIP(host string) (addrs []IP, err error) {
+ return lookupIPMerge(host)
+}
+
var lookupGroup singleflight
// lookupIPMerge wraps lookupIP, but makes sure that for any given
@@ -42,12 +52,6 @@ func lookupIPMerge(host string) (addrs []IP, err error) {
return addrs, nil
}
-// LookupHost looks up the given host using the local resolver.
-// It returns an array of that host's addresses.
-func LookupHost(host string) (addrs []string, err error) {
- return lookupHost(host)
-}
-
func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
if deadline.IsZero() {
return lookupIPMerge(host)
@@ -85,12 +89,6 @@ func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
return
}
-// LookupIP looks up host using the local resolver.
-// It returns an array of that host's IPv4 and IPv6 addresses.
-func LookupIP(host string) (addrs []IP, err error) {
- return lookupIPMerge(host)
-}
-
// LookupPort looks up the port for the given network and service.
func LookupPort(network, service string) (port int, err error) {
return lookupPort(network, service)
コアとなるコードの解説
このコミットのコアとなる変更は、src/pkg/net/lookup.go
ファイル内の以下の2点です。
-
インポート宣言の簡素化:
- 元のコードでは、
time
パッケージのインポートが複数行のブロック形式で記述されていました。 - 変更後、これが単一行の
import "time"
に修正されました。 - これはGoの慣習に沿ったもので、単一のパッケージをインポートする際にはこの形式が推奨されます。コードの見た目をすっきりとさせ、
gofmt
やgoimports
といったGoの標準的なフォーマッタとの整合性を高めます。機能的な影響は全くありません。
- 元のコードでは、
-
LookupHost
とLookupIP
関数の移動:LookupHost
とLookupIP
は、それぞれホスト名からアドレスを解決するための公開関数です。- 元のコードでは、これらの関数はファイル内の比較的離れた位置に定義されていました。
- このコミットでは、これらの関数が
protocols
マップとlookupGroup
変数の直後に移動されました。protocols
は、ネットワークプロトコルに関する定数を定義しています。lookupGroup
は、singleflight
パッケージ(golang.org/x/sync/singleflight
)のインスタンスであり、同じDNSルックアップリクエストが複数回発行された場合に、実際のルックアップ処理を一度だけ実行し、その結果を共有することで効率化を図るためのものです。
- この移動の意図は、これらの公開関数が内部的に利用するデータ構造やヘルパー(
lookupGroup
を介した重複排除ロジックなど)の近くに配置することで、コードの局所性を高め、関連するコードがまとまって読めるようにすることです。これにより、開発者がlookup.go
ファイルを見たときに、IPルックアップに関する主要な公開APIとその背後にある主要なメカニズムをより迅速に把握できるようになります。
これらの変更は、コードの機能的な振る舞いには影響を与えませんが、Goのコードベース全体の品質、特に可読性と保守性を向上させるための重要なリファクタリングです。
関連リンク
- Go言語の
net
パッケージのドキュメント: https://pkg.go.dev/net golang.org/x/sync/singleflight
パッケージのドキュメント: https://pkg.go.dev/golang.org/x/sync/singleflight (このコミットの時点ではまだx/sync
にはなかったかもしれませんが、概念としては関連します)- Go Code Review Comments - Import Paths: https://go.dev/doc/effective_go#import_paths (インポート宣言のスタイルに関するGoの慣習)
参考にした情報源リンク
- Go言語の公式ドキュメント
- Go言語のソースコード(
src/pkg/net/lookup.go
) - Goコミュニティでの一般的なコーディングスタイルとリファクタリングのプラクティス
singleflight
パッケージの概念に関する一般的な情報