Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11959] ファイルの概要

このコミットは、Go言語の標準ライブラリであるnet/urlパッケージ内のURL型のメソッドにおけるレシーバ変数名を統一(正規化)する変更です。具体的には、ParseメソッドとResolveReferenceメソッドのレシーバ名がbaseからuに変更されています。これは、Goのコーディング規約に沿った可読性向上のためのリファクタリングであり、機能的な変更は含まれていません。

コミット

commit 2f8d94fe4b583a3c94014740db77f6d0e9a69c3f
Author: David Symonds <dsymonds@golang.org>
Date:   Thu Feb 16 15:07:54 2012 +1100

    net/url: regularise receiver names.
    
    Update #2946.
    
    R=golang-dev, bradfitz, bradfitz
    CC=golang-dev
    https://golang.org/cl/5674065

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/2f8d94fe4b583a3c94014740db77f6d0e9a69c3f

元コミット内容

diff --git a/src/pkg/net/url/url.go b/src/pkg/net/url/url.go
index a9ce3b31e2..834247bd76 100644
--- a/src/pkg/net/url/url.go
+++ b/src/pkg/net/url/url.go
@@ -589,15 +589,15 @@ func (u *URL) IsAbs() bool {
 	return u.Scheme != ""
 }
 
-// Parse parses a URL in the context of a base URL.  The URL in ref
+// Parse parses a URL in the context of the receiver.  The provided URL
 // may be relative or absolute.  Parse returns nil, err on parse
 // failure, otherwise its return value is the same as ResolveReference.
-func (base *URL) Parse(ref string) (*URL, error) {
+func (u *URL) Parse(ref string) (*URL, error) {
 	refurl, err := Parse(ref)
 	if err != nil {
 		return nil, err
 	}
-	return base.ResolveReference(refurl), nil
+	return u.ResolveReference(refurl), nil
 }
 
 // ResolveReference resolves a URI reference to an absolute URI from
@@ -606,13 +606,13 @@ func (base *URL) Parse(ref string) (*URL) {
 // URL instance, even if the returned URL is identical to either the
 // base or reference. If ref is an absolute URL, then ResolveReference
 // ignores base and returns a copy of ref.
-func (base *URL) ResolveReference(ref *URL) *URL {
+func (u *URL) ResolveReference(ref *URL) *URL {
 	if ref.IsAbs() {
 		url := *ref
 		return &url
 	}
 	// relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
-	url := *base
+	url := *u
 	url.RawQuery = ref.RawQuery
 	url.Fragment = ref.Fragment
 	if ref.Opaque != "" {
@@ -632,7 +632,7 @@ func (base *URL) ResolveReference(ref *URL) *URL {
 	\turl.Path = ref.Path
 	} else {
 	\t// The "rel_path" case.
-\t\tpath := resolvePath(base.Path, ref.Path)
+\t\tpath := resolvePath(u.Path, ref.Path)
 	\tif !strings.HasPrefix(path, "/") {
 	\t\tpath = "/" + path
 	\t}

変更の背景

このコミットの背景には、Go言語のコーディングスタイルガイドラインにおけるレシーバ名の推奨事項があります。Goでは、メソッドのレシーバ名は短く、その型を表す一文字または数文字の略語を使用することが慣例とされています。この変更は、net/urlパッケージ内のURL型に対するメソッドのレシーバ名が、既存のbaseからuへと変更され、Goコミュニティ全体で推奨されるスタイルに統一することを目的としています。

コミットメッセージにあるUpdate #2946は、GoのIssueトラッカーにおけるIssue 2946: net/url: regularise receiver namesに対応しています。このIssueでは、net/urlパッケージ内のレシーバ名が不統一である点が指摘されており、特にURL型に対するメソッドでbaseというレシーバ名が使われていることが挙げられています。このbaseという名前は、URL型が「ベースURL」として機能する場合にのみ適切であり、一般的なURL型のメソッドではより汎用的な短い名前が望ましいとされました。このコミットは、そのIssueに対する直接的な解決策として提出されました。

前提知識の解説

Go言語のレシーバ

Go言語では、関数を特定の型に関連付けることで「メソッド」を定義します。この際、メソッドが操作するインスタンスは「レシーバ」として指定されます。レシーバは、関数名の前に括弧で囲んで宣言されます。

例:

type MyType struct {
    Value int
}

// (t MyType) はレシーバ。t はレシーバ変数名。
func (t MyType) GetValue() int {
    return t.Value
}

// (p *MyType) はポインタレシーバ。p はレシーバ変数名。
func (p *MyType) SetValue(newValue int) {
    p.Value = newValue
}

レシーバ名の慣例

Goの公式ドキュメントやコミュニティの慣例では、レシーバ変数名について以下の推奨事項があります。

  1. 短く、簡潔に: レシーバ名は、その型を表す一文字または数文字の略語を使用することが推奨されます。例えば、*Buffer型ならb*Client型ならc*URL型ならuなどです。
  2. 一貫性: 同じ型に対するすべてのメソッドで、同じレシーバ名を使用すべきです。これにより、コードの可読性が向上し、どのメソッドがどの型に属しているかを一目で理解しやすくなります。
  3. 自己参照的: レシーバ名は、そのメソッドが操作するインスタンス自身を指すため、thisselfのようなキーワードのGo版と考えることができます。

この慣例は、コードの冗長性を減らし、Goのミニマリストな設計思想に合致しています。

net/urlパッケージ

net/urlパッケージは、URL(Uniform Resource Locator)の解析、構築、操作を行うための機能を提供します。ウェブアプリケーションやネットワークプログラミングにおいて、URLのエンコード/デコード、パスの結合、クエリパラメータの操作など、多岐にわたる処理で利用されます。

  • url.URL構造体: URLの各要素(スキーム、ホスト、パス、クエリなど)を保持する構造体です。
  • Parse関数: 文字列から*URLを解析します。
  • ResolveReferenceメソッド: ベースURLと相対URLを結合して絶対URLを解決します。

技術的詳細

このコミットは、src/pkg/net/url/url.goファイル内のURL型に定義されている二つのメソッド、ParseResolveReferenceのレシーバ名を変更しています。

変更前:

  • func (base *URL) Parse(ref string) (*URL, error)
  • func (base *URL) ResolveReference(ref *URL) *URL

変更後:

  • func (u *URL) Parse(ref string) (*URL, error)
  • func (u *URL) ResolveReference(ref *URL) *URL

この変更は、メソッドのシグネチャと内部でのレシーバ変数の使用箇所に影響を与えます。

  1. Parseメソッド:

    • 変更前はbaseというレシーバ名が使われていました。このメソッドは、レシーバであるbase URLのコンテキストでrefという文字列のURLを解析し、絶対URLを返します。
    • 変更後はuというレシーバ名になりました。これにより、このメソッドがURL型のインスタンスに対して一般的な操作を行うことをより明確に示しています。内部ではbase.ResolveReference(refurl)u.ResolveReference(refurl)に変更されています。
  2. ResolveReferenceメソッド:

    • 同様に、変更前はbaseというレシーバ名が使われていました。このメソッドは、レシーバであるbase URLを基準として、refというURLインスタンスを解決し、絶対URLを返します。
    • 変更後はuというレシーバ名になりました。内部ではurl := *baseurl := *uに、path := resolvePath(base.Path, ref.Path)path := resolvePath(u.Path, ref.Path)に変更されています。

これらの変更は、コードの動作には一切影響を与えません。コンパイラはレシーバ変数名を単なる識別子として扱うため、baseであろうとuであろうと、その変数が指すメモリ上の値は同じです。この変更の唯一の目的は、Goのコーディング規約に準拠し、コードベース全体の一貫性と可読性を向上させることです。特に、URL型が常に「ベース」として機能するわけではないため、より汎用的なuという名前が適切と判断されました。

コアとなるコードの変更箇所

src/pkg/net/url/url.goファイルにおいて、以下の行が変更されました。

  • Parseメソッドのレシーバ名と内部参照:

    • -func (base *URL) Parse(ref string) (*URL, error) {
    • +func (u *URL) Parse(ref string) (*URL, error) {
    • - return base.ResolveReference(refurl), nil
    • + return u.ResolveReference(refurl), nil
  • ResolveReferenceメソッドのレシーバ名と内部参照:

    • -func (base *URL) ResolveReference(ref *URL) *URL {
    • +func (u *URL) ResolveReference(ref *URL) *URL {
    • - url := *base
    • + url := *u
    • - path := resolvePath(base.Path, ref.Path)
    • + path := resolvePath(u.Path, ref.Path)

コアとなるコードの解説

このコミットは、Go言語のメソッドにおけるレシーバ名の変更という、純粋なリファクタリングです。

func (base *URL) Parse(ref string) のようなメソッド定義では、括弧内の base *URL がレシーバの宣言です。ここで base はレシーバ変数名であり、メソッド本体内でこの変数名を使ってレシーバのフィールドや他のメソッドにアクセスします。

例えば、Parseメソッド内の base.ResolveReference(refurl) は、現在の URL インスタンス(この場合は base と名付けられたもの)の ResolveReference メソッドを呼び出しています。

このコミットでは、このレシーバ変数名を base から u に変更しました。

  • base は「基底」や「基準」といった意味合いが強く、ParseResolveReferenceメソッドが常に「基底URL」として振る舞うわけではないという文脈で、より汎用的なu(URLの略)が適切と判断されました。
  • Goのコーディング規約では、レシーバ名は短く、その型を簡潔に表すものが推奨されます。URL型に対してはuがその慣例に合致します。

この変更は、コンパイル後のバイナリや実行時のパフォーマンスに影響を与えるものではなく、コードの可読性とGoのコーディングスタイルガイドラインへの準拠を目的としています。これにより、net/urlパッケージのコードベース全体でレシーバ名の命名規則が一貫し、将来のメンテナンスや新規開発者がコードを理解する際の障壁が低減されます。

関連リンク

参考にした情報源リンク