1

次の関数は、一連のシステム コールを実行して、マップされたファイル バッファーを拡大します。

func (file *File) Ensure(more int) (err error) {
    if file.Append+more <= cap(file.Buf) {
        return
    }

    // there is not enough room
    if err = syscall.Munmap(file.Buf); err != nil {
        return
    }
    if _, err = file.Fh.Seek(0, os.SEEK_END); err != nil {
        return
    }
    if _, err = file.Fh.Write(make([]byte, file.Growth)); err != nil {
        return
    }
    if err = file.Fh.Sync(); err != nil {
        return
    }
    if file.Buf, err = syscall.Mmap(int(file.Fh.Fd()), 0, cap(file.Buf)+file.Growth, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED); err != nil {
        return
    }
    return
}

5 つのシステム コールが 5 行で行われ、11行のエラー処理コードがあります。これを行うためのよりクリーンな方法はありますか?

4

2 に答える 2

1

あなたの例では、エラー チェック パターンが適切であることはあまり明らかではありません。これを JVM や同様の言語と比較すると、これらの呼び出しのそれぞれで例外がスローされ、そのパターンははるかに少ない行数で、はるかに手間がかかりません。

ただし (これは大きな「ただし」です)、他のケースでは、各エラー ケースを他のケースとは異なる方法で処理する必要がある場合があります。Go スタイルでは、これは簡単です。例外スタイルではそうではありません。代わりに、多くの try-catch ブロックが必要になり、必要なセレモニーの量が逆になります。

私の結論は、囲碁パターンは少し雑用だと思うということですが、それが良いことであり、それが雑用を補う場合があることを感謝しています。また、起動コードで多くのことを使用しpanicているため、本質的に回復不能なものから回復する必要はありません。

最後に、関数型プログラミングの専門家 (Scala など)Eitherは、関数が結果またはエラーを返すいわゆるパターンを好みます。これは、例外を使用するより優先されます。本当に囲碁と同じパターンです。

于 2013-05-18T17:42:45.680 に答える