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

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

このコミットは、Go言語の標準ライブラリである compress/flate パッケージから WrongValueError 型を削除し、エラーハンドリングを標準的な fmt.Errorf を使用するように変更するものです。これは、Go 1リリースに向けたAPIの整理と簡素化の一環として行われました。

コミット

  • コミットハッシュ: 22636be8b03c2581ed0f6c93d90689b0202b87b0
  • Author: Nigel Tao nigeltao@golang.org
  • Date: Sat Feb 11 12:09:11 2012 +1100
  • コミットメッセージ:
    flate: delete WrongValueError type.
    
    Fixes #2838.
    
    R=rsc, r
    CC=golang-dev
    https://golang.org/cl/5651060
    

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

https://github.com/golang/go/commit/22636be8b03c2581ed0f6c93d90689b0202b87b0

元コミット内容

flate: delete WrongValueError type.

Fixes #2838.

R=rsc, r
CC=golang-dev
https://golang.org/cl/5651060

変更の背景

このコミットは、Go言語がバージョン1.0として正式リリースされる前の段階で行われた、標準ライブラリのAPI整理と安定化の一環です。特に compress/flate パッケージにおいて、特定の不正な値(この場合は圧縮レベル)が渡された際に返されるカスタムエラー型 WrongValueError が存在していました。

Go言語の設計思想では、エラーハンドリングはシンプルかつ統一的なアプローチが推奨されます。カスタムエラー型を乱立させるのではなく、可能な限り標準の error インターフェースと、エラーメッセージを生成するための fmt.Errorf を使用することが一般的です。

この WrongValueError は、圧縮レベルが範囲外であった場合にのみ使用される特殊なエラー型であり、Go 1のリリースに向けてAPIをより簡潔で一貫性のあるものにするため、このカスタムエラー型を削除し、標準的なエラーメッセージに置き換えることが決定されました。これにより、ライブラリの利用者はより予測可能なエラーハンドリングを行うことができ、コードの複雑性も軽減されます。

コミットメッセージにある Fixes #2838 は、Goプロジェクト内部の課題追跡システムにおける特定の課題番号を指している可能性が高いですが、公開されているGitHubのIssue #2838は vim-go プラグインのGoDoc表示に関するものであり、このコミットとは直接関連がないようです。これは、Goプロジェクトが内部で異なる課題管理システムを使用していたか、あるいは番号が重複している可能性を示唆しています。

前提知識の解説

compress/flate パッケージ

compress/flate はGo言語の標準ライブラリの一部であり、DEFLATEアルゴリズム(RFC 1951で定義)に基づくデータ圧縮および伸長機能を提供します。DEFLATEは、LZ77アルゴリズムとハフマン符号化を組み合わせたもので、ZIP、gzip、PNGなどの多くのファイル形式やプロトコルで広く使用されています。

このパッケージは、データのストリームを圧縮したり、圧縮されたデータを伸長したりするための ReaderWriter インターフェースを提供します。NewWriterNewWriterDict などの関数を使用して、圧縮レベルを指定して flate.Writer を作成できます。圧縮レベルは通常、-1(デフォルト)、0(圧縮なし)、1-9(高速から高圧縮)の範囲で指定されます。

Go言語のエラーハンドリング

Go言語では、エラーは組み込みの error インターフェースによって表現されます。このインターフェースは、Error() string という単一のメソッドを持ち、エラーの文字列表現を返します。

type error interface {
    Error() string
}

関数がエラーを返す場合、通常は戻り値の最後の要素として error 型を返します。慣例として、エラーがない場合は nil を返します。

func doSomething() (resultType, error) {
    // ... 処理 ...
    if someErrorCondition {
        return zeroValue, fmt.Errorf("something went wrong: %w", err) // エラーを返す
    }
    return actualResult, nil // 成功を返す
}

fmt.Errorf 関数は、フォーマットされた文字列から新しい error 値を作成するための標準的な方法です。これにより、カスタムエラー型を定義することなく、エラーメッセージに動的な情報を含めることができます。

カスタムエラー型

Goでは、特定の種類の情報をエラーに付加したい場合や、エラーの種類に基づいて異なる処理を行いたい場合に、カスタムエラー型を定義することがあります。例えば、以下のような構造体でエラーを表現できます。

type MyCustomError struct {
    Code    int
    Message string
}

func (e *MyCustomError) Error() string {
    return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}

しかし、Goの設計思想では、カスタムエラー型は本当に必要な場合にのみ使用し、可能な限り標準の error インターフェースと fmt.Errorf を使用してエラーメッセージを生成することが推奨されます。これにより、APIのシンプルさと一貫性が保たれます。

技術的詳細

このコミットの主要な技術的変更点は、compress/flate パッケージにおけるカスタムエラー型 WrongValueError の削除と、それを使用していた箇所の標準的なエラーハンドリングへの置き換えです。

  1. WrongValueError 型の削除: src/pkg/compress/flate/huffman_bit_writer.go ファイルから、WrongValueError 構造体の定義と、その Error() メソッドが完全に削除されました。

    // 削除されたコード
    type WrongValueError struct {
        name  string
        from  int32
        to    int32
        value int32
    }
    
    func (err WrongValueError) Error() string {
        return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.FormatInt(int64(err.from), 10) + ";" +
            strconv.FormatInt(int64(err.to), 10) + "] but actual value is " + strconv.FormatInt(int64(err.value), 10)
    }
    

    この型は、特定の引数(この場合は圧縮レベル)が期待される範囲外であった場合に、その引数の名前、期待される範囲、実際の値を詳細に伝えるために設計されていました。

  2. エラー生成の変更: src/pkg/compress/flate/deflate.go ファイルの (*compressor).init メソッド内で、圧縮レベルが不正な場合に WrongValueError を返す代わりに、fmt.Errorf を使用してエラーメッセージを生成するように変更されました。

    --- a/src/pkg/compress/flate/deflate.go
    +++ b/src/pkg/compress/flate/deflate.go
    @@ -390,7 +391,7 @@ func (d *compressor) init(w io.Writer, level int) (err error) {
     		td.fill = (*compressor).fillDeflate
     		td.step = (*compressor).deflate
     	default:
    -		return WrongValueError{"level", 0, 9, int32(level)}
    +		return fmt.Errorf("flate: invalid compression level %d: want value in range [-1, 9]", level)
     	}
     	return nil
     }
    

    これにより、エラーメッセージは「flate: invalid compression level %d: want value in range [-1, 9]」という形式になり、不正な圧縮レベルが直接メッセージに埋め込まれます。

  3. ドキュメントの更新: doc/go1.htmldoc/go1.tmpl のGo 1リリースノートのドラフトが更新され、compress/flate パッケージの変更点として WrongValueError 型が削除されたことが明記されました。

    <p>
    In Go 1, the <code>NewWriterXxx</code> functions in
    <a href="/pkg/compress/flate"><code>compress/flate</code></a>,
    <a href="/pkg/compress/gzip"><code>compress/gzip</code></a> and
    <a href="/pkg/compress/zlib"><code>compress/zlib</code></a>
    all return <code>(*Writer, error)</code> if they take a compression level,
    and <code>*Writer</code> otherwise. Package <code>gzip</code>'s
    <code>Compressor</code> and <code>Decompressor</code> types have been renamed
    to <code>Writer</code> and <code>Reader</code>. Package <code>flate</code>'s
    <code>WrongValueError</code> type has been removed.
    </p>
    

    この変更は、Go 1のAPI安定化とドキュメント整備の重要性を示しています。

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

このコミットで変更された主要なファイルは以下の通りです。

  • doc/go1.html: Go 1リリースノートのHTMLドキュメント。compress/flate パッケージの変更(WrongValueError の削除)が追記されました。
  • doc/go1.tmpl: Go 1リリースノートのテンプレートファイル。doc/go1.html と同様の変更が加えられました。
  • src/pkg/compress/flate/deflate.go: compress/flate パッケージのDEFLATE圧縮ロジックを実装するファイル。compressor 構造体の init メソッド内で、不正な圧縮レベルに対するエラー生成が WrongValueError から fmt.Errorf に変更されました。
  • src/pkg/compress/flate/huffman_bit_writer.go: compress/flate パッケージのハフマン符号化ビットライターを実装するファイル。WrongValueError 型の定義とその Error() メソッドが完全に削除されました。

コアとなるコードの解説

src/pkg/compress/flate/deflate.go の変更

このファイルでは、compressor 構造体の init メソッドが変更されました。このメソッドは、flate.Writer の初期化時に圧縮レベルを設定する役割を担っています。

変更前は、level 引数が有効な範囲(-1から9)外であった場合、以下のように WrongValueError を生成して返していました。

// 変更前
default:
    return WrongValueError{"level", 0, 9, int32(level)}

変更後は、fmt.Errorf を使用して、より一般的なエラーメッセージを生成するように修正されました。

// 変更後
default:
    return fmt.Errorf("flate: invalid compression level %d: want value in range [-1, 9]", level)

この変更により、compress/flate パッケージのエラーハンドリングがGoの標準的な慣習に沿うようになり、カスタムエラー型に依存しないシンプルなエラー報告が可能になりました。

src/pkg/compress/flate/huffman_bit_writer.go の変更

このファイルからは、WrongValueError 型の定義が完全に削除されました。

// 削除されたコード
type WrongValueError struct {
    name  string
    from  int32
    to    int32
    value int32
}

func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
    // ...
}

func (err WrongValueError) Error() string {
    return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.FormatInt(int64(err.from), 10) + ";" +
        strconv.FormatInt(int64(err.to), 10) + "] but actual value is " + strconv.FormatInt(int64(err.value), 10)
}

この型は、deflate.go でのみ使用されていたため、deflate.go でのエラー生成方法が変更されたことにより、このカスタムエラー型は不要となり削除されました。これにより、コードベースから不要な複雑性が取り除かれ、ライブラリの保守性が向上しました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント: エラーハンドリング、パッケージの構造に関する一般的な情報。
  • GitHub Issue #2838 (vim-go): https://github.com/fatih/vim-go/issues/2838 (このコミットの Fixes #2838 とは直接関連がない可能性が高い)
  • DEFLATEアルゴリズム (RFC 1951): compress/flate の基盤となる圧縮アルゴリズム。
  • Go言語の fmt パッケージドキュメント: fmt.Errorf の使用方法に関する情報。