NopCloser: Go でアクションを閉じずにクローザー
Go では、io/ioutil.NopCloser 関数は、実際の Close メソッド実装のない io.ReadCloser インターフェイス。基本的に、提供された Reader を ReadCloser にラップしますが、Close への呼び出しはすべて無視されます。
公式ドキュメントでは、NopCloser を「提供された Reader r をラップする no-op Close メソッドを持つ ReadCloser を返す」と定義しています。
NopCloser を使用する場合
NopCloser は特に証明されますio.ReadCloser を返す必要があるが、閉じるための基になるリソースがない場合に便利です。 Reader を NopCloser でラップすると、その Close メソッドが存在することが保証され、リソースのクリーンアップを手動で管理する必要がなくなります。
メモリからデータを読み取るカスタム HTTP ハンドラーを実装するシナリオを考えてみましょう。
type MemReader struct { data []byte } func (r *MemReader) Read(p []byte) (n int, err error) { copy(p, r.data) return len(r.data), nil }
ハンドラーは次のようになります:
func handler(w http.ResponseWriter, r *http.Request) { // Read data from memory. data := MemReader{[]byte("Hello World!")} io.Copy(w, &data) }
この場合、 MemReader には Close メソッドがないため、ハンドラーから直接 &data を返すと、http.Handler インターフェイス (リクエスト本文の読み取りに io.ReadCloser が必要となります) に違反します。これを解決するには、MemReader を NopCloser でラップします。
type MemReader struct { data []byte } func (r *MemReader) Read(p []byte) (n int, err error) { copy(p, r.data) return len(r.data), nil } func handler(w http.ResponseWriter, r *http.Request) { data := MemReader{[]byte("Hello World!")} io.Copy(w, ioutil.NopCloser(&data)) }
これにより、不必要なリソース管理を導入することなく http.Handler インターフェイスが維持されます。
使用例
NopCloser を使用するもう 1 つの実際的な例は、データを生成するがデータを必要としない関数がある場合です。リソースを閉じる:
func generateData() *strings.Reader { return ioutil.NopCloser(strings.NewReader("Generated data")) }
このシナリオでは、NopCloser を使用すると、実際のクリーンアップ操作を行わずに *strings.Reader が io.ReadCloser インターフェイスを満たすことができます。
以上がGo の ioutil.NopCloser をいつ使用する必要がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。