コンピュータ プログラミングにおいて、ガードとは、プログラムの実行が問題の分岐で継続される場合に true と評価される必要があるブール式です。使用するプログラミング言語に関係なく、ガード句、ガード コード、またはガード ステートメントは、実行中にエラーを回避するために使用される整合性の前提条件のチェックです。
用途
典型的な例としては、処理しようとしている参照がnull でないことを確認することで、 null ポインター障害を回避します。
その他の用途としては、 Dispose パターンのように、 ブール型フィールドをべき等性のために使用する(そのため、後続の呼び出しはnopになる)ことが挙げられます。
public String foo ( String username ) { if ( username == null ) { throw new IllegalArgumentException ( "ユーザー名が null です。" ); }
// メソッドコードの残りはここに続きます...
}
ネストが少なく、よりフラットなコード
ガードはサブルーチンからの早期終了を提供し、構造化プログラミングから逸脱する一般的な方法であり、ネストのレベルを1つ削除して、よりフラットなコードを実現します。[1]を に置き換えます。
if guard { ... }if not guard: return; ...
ガード句の使用は、コードを改善するためのリファクタリング手法になります。一般的に、ネストが少ないほど、コードが簡素化され、認知的負担が軽減されるため、効果的です。
たとえば、Pythonでは次のようになります。
# この関数にはガード句がありません
def f_noguard ( x ):
if isinstance ( x , int ):
#code
#code
#code
return x + 1
else :
return None
# ガード句を使用した同等の関数。ほとんどのコードはインデントが少なく、読みやすく、理解しやすいことに注意してください。
def f_guard ( x ):
if not isinstance ( x , int ):
return None
#code
#code
#code
return x + 1
Cで書かれた別の例:
// この関数にはガード句がありません
int funcNoGuard ( int x ) { if ( x >= 0 ) { //code //code //code return x + 1 ; } else { return 0 ; } }
// ガード句を持つ同等の関数
int funcGuard ( int x ) { if ( x < 0 ) { return 0 ; }
//コード
//コード//コードreturn x + 1 ; }
用語
この用語は、 APL、Haskell、Clean、Erlang、occam、Promela、OCaml、Swift、[2] Pythonバージョン 3.10 以降、およびScalaプログラミング言語で特定の意味で使用されます。[要出典] Mathematicaでは、ガードは制約と呼ばれます。ガードは、形式手法の言語であるGuarded Command Languageの基本概念です。ガードを使用すると、構造が一致してもパターンをスキップする可能性を含めてパターン マッチングを拡張できます。条件文のブール式も条件と呼ばれますが、通常はこのガードの定義に適合します。
数学
次の Haskell の例では、ガードは「|」と「=」の各ペアの間に発生します。
f x | x > 0 = 1 |それ以外の場合= 0
これは、それぞれの数学表記法に似ています。
この場合、ガードは「if」節と「otherwise」節にあります。
複数の警備員
複数の並列ガードがある場合、通常は上から下の順序で試行され、最初に通過したブランチが選択されます。ケースのリスト内のガードは通常並列です。
ただし、Haskell のリスト内包表記ではガードは連続しており、ガードのいずれかが失敗すると、リスト要素は生成されません。これは、ガード間に他のリスト内包表記句が存在する可能性があることを除けば、 個別のガードを論理 ANDで組み合わせるのと同じです。
進化
1963 年のCPLにすでに存在していた単純な条件式には、最初のサブ式に対するガードと、最初のサブ式が使用できない場合に使用する別のサブ式があります。これを記述する一般的な方法は次のとおりです。
(x>0) -> 1/x; 0 x>0 ? 1/x : 0
2 番目のサブ式をさらに単純な条件式にできる場合は、最後のフォールスルーの前に試すための選択肢をさらに提供できます。
(x>0) -> 1/x; (x<0) -> -1/x; 0
1966 年のISWIMには、必須のフォールスルー ケースのない条件式の形式があり、これにより、ガードは、どちらかを選択するという概念から切り離されました。ISWIM の場合、どの選択肢も使用できない場合、値はundefinedになり、値として計算されないように定義されていました。
KRCはSASL (1976)の「小型版」[3]であり、「ガード」という用語を使用した最初のプログラミング言語の1つでした。その関数定義には複数の節があり、各節に続くガードに基づいて適用する節が選択されました。
fac n = 1 、n = 0 = n * fac ( n - 1 )、n > 0
ガード句の使用と「ガード句」という用語は、少なくとも1990年代のSmalltalkの実践にまで遡り、 Kent Beckによって体系化されました。[1]
1996年、Dyalog APLは、ガードが唯一の制御構造である代替の純粋関数型スタイルを採用しました。[4]このAPLの例では、入力数値のパリティを計算します。
パリティ← {
2 ∣ ⍵ : '奇数' '偶数' }
パターンガード
パターンに付加されたガードに加えて、パターン ガードはガードのコンテキストでのパターン マッチングの使用を指すこともあります。実際には、パターンの一致はパスを意味すると解釈されます。この意味は、1997 年 4 月にSimon Peyton Jonesが Haskell に提案した「ガードの新しい見方」で導入され、提案の実装に使用されました。この機能により、パターンのガードでパターンを使用できるようになります。
拡張 Haskell の例:
clunky env var1 var2 | val1 <- lookup env var1のみ、val2 < - lookup env var2 = val1 + val2 -- ...clunky のその他の式...
これは次のように記述されます。「環境と 2 つの変数の場合、環境からの変数の検索で値が生成されると、値の合計になります。...」リストの内包表記と同様に、ガードは直列になっており、ガードのいずれかが失敗すると分岐は実行されません。
参照
- 主張
- ガードコマンド言語、非決定論的条件に基づくプログラミング言語
- ガードサスペンション
- アイバーソンブラケット
- 論理条件
- センチネルノード、データ構造の終わりを表すオブジェクト
- スイッチ文
参考文献
- ^ ab Beck, Kent (1997). 「ガード句」。Smalltalk ベスト プラクティス パターン、 pp. 178–179。
- ^ Cook, Nate. 「guard & defer」NSHipster . 2016年2月26日閲覧。
- ^ Turner, DA「関数型プログラミング言語の歴史」(PDF)。
- ^ Scholes, John. 「Dyalog APL の直接関数」(PDF)。
外部リンク
- Free On-Line Dictionary of Computingの Guard - FOLDOC 、Denis Howe (編集者)。
- ガード条項、WikiWikiWeb
- Haskell 98 レポート、第 3 章「式」。
- Mathematica ブック、セクション 2.3.5 パターンに制約を課す
- Glorious Glasgow Haskell コンパイルシステム ユーザーズガイド、バージョン 6.4、セクション 7.3.2。パターンガード
