web-dev-qa-db-ja.com

ガードブロックを下に移動

時々、ガードブロックを設けるのは良い考えです:

ガードブロックは、特殊なケースからガードします。

GetFiletype(Ext)
{
    ; Guard block
    If (!Ext || Ext != "txt" && Ext != "md")
        Return "Not supported file type"

    ; Processing block
    If (Ext = "txt")
        Return "Plain text"
    Else
        Return "Markdown"
}

ただし、このコードは別の方法で記述できます。

GetFiletype(Ext)
{
    ; Processing block
    If (Ext = "txt")
        Return "Plain text"
    Else If (Ext = "md")
        Return "Markdown"

    ; Does this part have a name?
    Else
        Return "Not supported file type"
}

ご覧のとおり、ガードブロックは下に移動されているため、「ガード」と呼ぶのは愚かで不正確です。

この部分に「アンチガード」や「ファイアエグジット」のような名前はありますか?

2
john c. j.

[Wikipedia]によると、「...ガードは、プログラムの実行が問題のブランチで継続する場合にtrueと評価される必要があるブール式です... "。

したがって、最初のコード例では、関数が返すデフォルト値"Markdown"があります。また、2つのガードがあり、それらのガードが満たされた場合は"Not supported file type"または"Plain text"が返されます。

2番目の例では、これらのデフォルト値とガード値を切り替えました。ガードはまだ残っていますが、エラー状態ではなく「ハッピーパス」の結果を処理するようになりました。

しかし、同じ記事で言及されているように、「ガードコード "/」ガード句"/"ガードブロックという用語は、例でサポートされていないファイルタイプなどのエラーから保護するガード。したがって、"Not supported file type"コードをガードから外してデフォルトパスに移動すると、正しく言うようにガード句がなくなります。

したがって、それを何と呼ぶか​​については、ガード句が前提条件であるため、関数の最後にエラーから保護するためのデフォルト値を事後条件として置くことを参照します。その事後条件にガードは必要ありません。それは単に最後に失敗を一掃するだけです。

これに対する補足として、コード例について他の2つのポイントがコメントで触れられており、ここで言及する価値があります。

最初に、2番目のバージョンは最初の例のように!Extを明示的に処理しないため、2つのコード例は同等ではないことに注意してください。 2番目の例では、Extのテストの重複を回避しますが、!Extチェックを失います。言語によっては、これがコードの動作に影響する場合があります。

次に、Elseはコードで冗長です。不要なブランチを作成しています。したがって、2つの例は次のように表すことができます。

GetFiletype(Ext)
{
    if (!Ext || Ext != "txt" && Ext != "md")
        Return "Not supported file type"

    If (Ext = "txt")
        Return "Plain text"

    Return "Markdown"
}

GetFiletype(Ext)
{
    If (Ext = "txt")
        Return "Plain text"

    If (Ext = "md")
        Return "Markdown"

    Return "Not supported file type"
}

次に、コードが一連のガードであり、いずれの場合も最後にデフォルトの結果が設定されていることが明らかになります。

2
David Arno