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

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

このコミットは、Go言語のバージョン1(Go 1)リリースに向けた言語仕様の変更点を公式ドキュメントに追記するものです。具体的には、複合リテラル、rune型、error型、そしてエクスポートされていないフィールドを持つ構造体のコピーに関する変更が記述されています。これらの変更は、Go言語の安定版リリースに向けて、言語の使いやすさと堅牢性を向上させるための重要なステップでした。

コミット

commit 2e338fa69f269e14d5dc1923c033c9a16b4bce5c
Author: Rob Pike <r@golang.org>
Date:   Fri Dec 9 08:31:57 2011 -0800

    doc/go1: the rest of the language changes
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/5478047

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

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

元コミット内容

doc/go1: the rest of the language changes

変更の背景

このコミットは、Go言語がバージョン1(Go 1)として正式リリースされる前の最終調整段階で行われたものです。Go 1は、Go言語の最初の安定版リリースであり、将来にわたって互換性を保証する重要なマイルストーンでした。このコミットの目的は、Go 1で導入される言語仕様の変更点、特に複合リテラルの改善、Unicode文字を扱うためのrune型の導入、標準エラーハンドリングのためのerrorインターフェースの定義、そして構造体のコピーに関する柔軟性の向上を公式ドキュメント(doc/go1.htmldoc/go1.tmpl)に反映させることでした。また、これらの変更を説明するためのサンプルコード(doc/progs/go1.go)も更新されています。

Go 1の目標は、言語の安定性と予測可能性を提供し、開発者が安心してGoを採用できるようにすることでした。そのため、言語のセマンティクスに関する曖昧さを排除し、より直感的で効率的なコーディングを可能にするための微調整が行われました。このコミットは、その一環として、特に開発者が日常的に遭遇する可能性のある型システムとデータ構造の扱いに焦点を当てています。

前提知識の解説

このコミットの変更点を理解するためには、以下のGo言語の基本的な概念と、Go 1リリース前の状況について知っておく必要があります。

  • 複合リテラル (Composite Literals): Go言語で配列、スライス、マップ、構造体などの複合型を初期化するための構文です。例えば、[]int{1, 2, 3}struct{x int}{x: 10}のように記述します。Go 1以前は、ポインタ型の要素を持つ複合リテラルにおいて、要素の型指定を省略できない場合がありました。
  • Unicodeと文字エンコーディング: コンピュータがテキストを扱う際、文字は数値として表現されます。Unicodeは、世界中のほとんどの文字を統一的に扱うための文字コード標準です。Go言語では、文字列はUTF-8エンコードされたバイト列として扱われます。個々のUnicodeコードポイント(文字)は、Go 1以前は通常int型で表現されていましたが、これは文字のセマンティクスを完全に表現するには不十分な場合がありました。
  • エラーハンドリング: Go言語では、エラーは戻り値として明示的に扱われます。Go 1以前は、エラーの表現方法に統一性がなく、開発者が独自にエラー型を定義する必要がありました。これにより、エラーの処理方法が一貫しないという問題がありました。
  • 構造体とエクスポートされていないフィールド: Go言語では、フィールド名が小文字で始まる構造体フィールドは、そのフィールドが定義されているパッケージ内からのみアクセス可能です(エクスポートされていないフィールド)。Go 1以前は、エクスポートされていないフィールドを持つ構造体をパッケージ外でコピーする際に、一部の制限がありました。

技術的詳細

このコミットでドキュメント化された主な変更点は以下の通りです。

  1. 複合リテラルにおけるポインタ型要素の型省略:

    • Go 1では、配列、スライス、マップの複合リテラルにおいて、要素がポインタ型である場合でも、要素の初期化子における型指定を省略できるようになりました。
    • 例: holiday4 := []*Date{{ "Feb", 14 }, { "Nov", 11 }} のように、&Date{...}ではなく{...}と記述できるようになりました。これにより、コードの冗長性が減り、可読性が向上します。
    • gofmt -sコマンドを既存のソースコードに適用することで、この新しい構文に自動的に変換することが可能です。
  2. rune型の導入:

    • Go 1では、個々のUnicodeコードポイントを表すための新しい組み込み型runeが導入されました。runeint32のエイリアスであり、byteuint8のエイリアスであるのと同様の関係です。
    • 文字リテラル(例: 'a', '語', '\u0345')は、デフォルトでrune型を持つようになりました。これにより、Unicode文字をより正確かつセマンティックに扱うことができるようになります。
    • unicodeパッケージなどの標準ライブラリも、適切な場所でintの代わりにruneを使用するように更新されました。
    • この変更は、ほとんどの既存のコードに影響を与えませんが、型推論によってrune型が暗黙的に導入されます。一部のコードでは、型エラーが発生する可能性がありますが、簡単な型変換で解決できます。
  3. error型の導入:

    • Go 1では、新しい組み込み型errorが導入されました。これは以下のインターフェースとして定義されています。
      type error interface {
          Error() string
      }
      
    • これにより、Go言語全体でエラーハンドリングの一貫性が確保されるようになりました。すべてのエラーはerrorインターフェースを実装することで、統一された方法で処理できるようになります。この変更の具体的な影響は、主に標準ライブラリのエラー処理に現れます。
  4. エクスポートされていないフィールドを持つ構造体のコピーの緩和:

    • Go 1では、エクスポートされていない(小文字で始まる)フィールドを持つ構造体へのアクセスルールが緩和されました。これにより、クライアントパッケージがそのような構造体を代入(およびコピー)することが許可されます。
    • クライアントパッケージは引き続き個々のエクスポートされていないフィールドにアクセスすることはできませんが、構造体全体の代入やコピーは可能になりました。これにより、内部状態を持つ構造体をより柔軟に扱うことができるようになります。
    • この変更は新しい機能であるため、既存のコードに影響を与えることはありません。

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

このコミットでは、以下のファイルが変更されています。

  • doc/go1.html: Go 1の言語変更点を説明する公式ドキュメントのHTML版。複合リテラル、rune型、error型、エクスポートされていないフィールドを持つ構造体のコピーに関するセクションが追加・更新されています。
  • doc/go1.tmpl: doc/go1.htmlのテンプレートファイル。HTML版と同様の変更が反映されています。
  • doc/progs/go1.go: doc/go1.htmlで参照されるGo言語のサンプルコード。複合リテラルとrune型の使用例が追加されています。

コアとなるコードの解説

doc/progs/go1.goに追加された主要なコードスニペットは以下の通りです。

複合リテラルの例

func compositeLiterals() {
	type Date struct {
		month string
		day   int
	}
	// Struct values, fully qualified; always legal.
	holiday1 := []Date{
		Date{"Feb", 14},
		Date{"Nov", 11},
		Date{"Dec", 25},
	}
	// Struct values, type name elided; always legal.
	holiday2 := []Date{
		{"Feb", 14},
		{"Nov", 11},
		{"Dec", 25},
	}
	// Pointers, fully qualified, always legal.
	holiday3 := []*Date{
		&Date{"Feb", 14},
		&Date{"Nov", 11},
		&Date{"Dec", 25},
	}
	// Pointers, type name elided; legal in Go 1.
	holiday4 := []*Date{
		{"Feb", 14},
		{"Nov", 11},
		{"Dec", 25},
	}
	// STOP OMIT
	_, _, _, _ = holiday1, holiday2, holiday3, holiday4
}

この例では、Date構造体のスライスを初期化する様々な方法を示しています。特にholiday4の例は、Go 1で新しく許可された、ポインタ型の要素を持つ複合リテラルで要素の型指定を省略する構文を示しています。これにより、&Date{...}と書く代わりに{...}と書くことができ、コードがより簡潔になります。

rune型の例

func runeType() {
	// STARTRUNE OMIT
	delta := 'δ' // delta has type rune.
	var DELTA rune
	DELTA = unicode.ToUpper(delta)
	epsilon := unicode.ToLower(DELTA + 1)
	if epsilon != 'δ'+1 {
		log.Fatal("inconsistent casing for Greek")
	}
	// ENDRUNE OMIT
}

この例では、rune型の基本的な使用法を示しています。文字リテラル'δ'rune型として推論され、unicodeパッケージの関数(ToUpper, ToLower)がrune型を引数に取り、rune型を返すことが示されています。これにより、Unicode文字の操作がより直感的かつ正確に行えるようになります。

関連リンク

参考にした情報源リンク