Swift 6.0 beta 日本語化計画 : Swift 6.0 beta
文
Swift には、三種類の文があります:単純な文、コンパイラ制御文、そしてフロー制御文です。単純な文は、最も一般的で、式または宣言のどちらかで構成されています。コンパイラ制御文は、プログラムに、コンパイラの動作の外観を変更することを可能とし、条件付きコンパイルブロックと行制御文が含まれます。
フロー制御文は、プログラム内での実行のフローを制御するために使用されます。Swift には、数種類のフロー制御文があり、ループ文、分岐文、および制御転送文を含みます。ループ文は、コードのブロックを繰り返し実行することを可能にし、分岐文は、決まった条件が満たされた場合のみ、決まったコードのブロックを実行することを可能にし、制御転送文は、コードが実行される順序を変更する方法を提供します。また、Swift はスコープを導入する do 文を提供し、エラーをキャッチして処理し、現在のスコープがちょうど終了する前にクリーンアップ操作を実行するための defer 文を提供します。
セミコロン (;) は、任意の文の後に書くことができ、同じ行に書いた場合には、複数の文を分離するために使用されます。
ループ文は、ループ内で指定された条件に応じて、コードのブロックが、繰り返し実行されることを可能にします。Swift には3つのループ文があります:for-in 文、while 文、および repeat-while 文です。
ループ文のフロー制御は、break 文と continue 文によって変更でき、以下の break 文 と、continue 文 で議論します。
for-in 文は、コードのブロックが Sequence プロトコルに準拠するコレクション (または any type(任意の型)) の各項目に対して一度実行できます。
for-in 文は以下の形式をとります。
for <#item#> in <#collection#> {
makeIterator( ) メソッドは、繰り返す型、つまり IteratorProtocol プロトコルに準拠する型の値を取得する コレクション 式に呼び出されます。プログラムは、繰り返しの next( ) メソッドを呼び出すことにより、ループの実行を開始します。返される値が nil でない場合、それは 項目(item) パターンに代入され、プログラムは 文 を実行し、ループの先頭で実行を継続します。そうでない場合、プログラムは代入を実行せず、文 を実行せず、for-in 文の実行を終了します。
while 文は、条件が true のままである限り、コードのブロックを繰り返し実行できます。
while 文の形式は以下のとおりです。
while <#condition#> {
while 文は以下のように実行されます。
文 が実行される前に 条件 の値が評価されるので、while 文の中の 文 は、ゼロ回以上実行されます。
条件 の値は、Bool 型か、Bool にブリッジされた型でなければなりません。Optional の結合 で説明したように、条件も optional の結合の宣言であることができます。
repeat-while 文は、条件が true のままであるかぎり、コードのブロックを、1回以上実行します。
repeat-while 文の形式は以下のとおりです。
repeat {
repeat-while 文は、以下のように実行されます:
文 が実行された後、条件 の値が評価されるので、repeat-while 文の 文 は、少なくとも一度実行されます。
条件 の値は Bool 型かもしくは Bool にブリッジした型でなければなりません。
分岐文は、プログラムが、1つ以上の条件の値に応じてコードの特定の部分を実行することを可能にします。分岐文で指定された条件の値は、プログラム分岐と、そのため、コードのどのブロックが実行されるかを制御します。Swift には、3つの分岐文があります:if 文、guard 文、そして switch 文です。
if 文あるいは switch 文のフロー制御は、break 文によって変更でき、以下の break 文 で説明されています。
if 文は、1つ以上の条件の評価に基づいてコードを実行するために使用されます。
if 文には2つの基本的な形式があります。各形式には、開き括弧と閉じ括弧が必要です。
最初の形式では、条件が true である場合にのみ、コードが実行され、以下の形式です:
if <#condition#> {
if 文の2番目の形式は、(else キーワードで導入される) 追加の else 句 を提供し、条件が true の場合、コードの一部を実行するために使用され、同じ条件が false の場合、コードの別の部分を実行するために使用されます。一つの else 句が存在している場合、if 文は以下の形式です:
if <#condition#> {
<#statements to execute if condition is true#>
} else {
<#statements to execute if condition is false#>
if 文の else 句は、1つ以上の条件をテストするために、別の if 文を含めることができます。一緒に連鎖している if 文は以下の形式のようになります。
if <#condition 1#> {
<#statements to execute if condition 1 is true#>
} else if <#condition 2#> {
<#statements to execute if condition 2 is true#>
} else {
<#statements to execute if both conditions are false#>
}
if 文の全ての条件の値は Bool 型かあるいは Bool にブリッジされた型でなければなりません。Optional の結合 で議論したように、条件も、optional の結合の宣言であることができます。
guard 文は、1つ以上の条件が満たされない場合、あるスコープの外からプログラムの制御を転送するために使用されます。
guard 文の形式は以下のとおりです。
guard <#condition#> else {
<#statements#>
}
guard 文の全ての条件値は、Bool 型であるか、Bool にブリッジされた型でなければなりません。Optional の結合 で議論したように、条件も、optional の結合の宣言であることができます。
guard 文の条件内の optional の結合の宣言から値を代入された定数または変数はスコープを取り囲む残りの guard 文に使用できます。
guard 文の else 句は必須であり、以下に挙げた文のいずれか一つを使用して、Never の戻り値の型を持つ関数を呼び出すか、または guard 文を取り囲むスコープの外へとプログラム制御を転送しなければなりません。
制御転送文については、以下の 制御転送文 で説明します。Never の戻り値の型を持つ関数の詳細については、Never を返す関数 を参照してください。
switch 文では、制御式の値に応じてコードの特定のブロックを実行することができます。
switch 文の形式は次のとおりです。
case <#pattern 1#>:
<#statements#>
case <#pattern 2#> where <#condition#>:
<#statements#>
case <#pattern 3 where <#condition#> ,
<#pattern 4#> where <#condition#>:
<#statements#>
default:
<#statements#>
}
switch 文の 制御式 は、評価され、それぞれの case で指定されたパターンと比較されます。一致する物が見つかった場合、プログラムはその case のスコープ内にリストされている 文 を実行します。各 case のスコープは、空にすることはできません。その結果、各 case ラベルのコロン (:) 以下に少なくとも一つの文を含めなければなりません。一致した case の本体内の全てのコードを実行しない場合には、一つの break 文を使用してください。
コードがその上で分岐できる式の値は、非常に柔軟です。例えば、整数や文字などのスカラー型の値に加えて、コードは、浮動小数点数、文字列、タプル、カスタムクラスのインスタンス、および optional を含む全ての型の値の上で分岐できます。制御式 の値が列挙型における case の値にも一致し、値の指定した範囲に含まれていてもチェックすることができます。switch 文の値のこれらの様々な型を使用する方法の例については、フロー制御 の章の Switch を参照してください。
switch の case は、必要に応じて各パターンの後に where 句を含めることができます。where 句 は式が続く where キーワードによって導入され、そして case 内のパターンが、制御式 に一致したと見なされる前に、追加の条件を提供するために使用されます。where 句が存在する場合、制御式 の値が case のパターンの1つと一致し、where 句の式が true と評価された場合にのみ、該当する case 内の 文 が実行されます。たとえば、(1、1) のように、同じ値の2つの要素を含むタプルである場合にのみ、以下の例の case には 制御式 が一致します。
上記の例が示すように、case 内のパターンはまた、let キーワードを使用して定数を結合できます (それらはまた、var キーワードを使用して変数を結合できます)。するとこれらの定数 (または変数) は、対応する where 句で参照でき、case のスコープ内のコードの残りの全ての部分を通じて参照できます。case が制御式に一致する、複数のパターンを含んでいる場合、すべてのパターンには同じ定数または変数結合が含まれていなければなりませんし、また、結合された各々の変数または定数は case のパターンすべてで同じ型でなければなりません。
switch 文はまた、default キーワードで導入されるデフォルトの case を含めることもできます。デフォルトの case 内のコードは、他の case が制御式に一致しない場合にのみ実行されます。switch 文は、デフォルトの case を一つだけ含められますが、switch 文の最後に表示しなければなりません。
パターン一致操作の実際の実行順序、および特に case のパターンの評価順序は特に規定されていませんが、評価はソースの順序で実行されているかのように、switch 文のパターン一致は、動作し、すなわち、ソースコードで表示される順序で動作します。結果として、複数の case が同じ値に評価されるパターンを含んでいる場合、そうすると制御式の値に一致できるため、プログラムは、ソースの順序で最初に一致した case 内のコードのみを実行します。
Swift では、制御式の型のすべての可能な値が、case の少なくとも1つのパターンの値と一致しなければなりません。これは単に実行可能でない場合には (例えば、制御式の型が Int であるとき)、要件を満たすデフォルトの case を含めることができます。
nofrozen (凍結されていない) 列挙型 は、アプリをコンパイルして出荷した後でも、将来的に新しい列挙型の case が発生する可能性がある特別な種類の列挙型です。凍結されていない列挙型を切り替えるには、特別な考慮が必要です。ライブラリの作成者が列挙型を nofrozen (凍結されていない) としてマークすると、新しい列挙型の case を追加する権利を保持します。また、その列挙型を操作するコードは全て、再コンパイする事なくそれらの将来の case を処理でき なければなりません。ライブラリ発展モードでコンパイルされたコード、Swift 標準ライブラリのコード、Apple フレームワーク用の Swift オーバーレイ、C および Objective-C コードは、nomfrozen (凍結されていない) 列挙型を宣言できます。frozen (凍結された) 列挙型と nonfrozen (凍結されていない) 列挙型の詳細については、frozen を参照してください。
nonfrozen (凍結されていない) 列挙型の値を切り替えるときは、列挙型のすべての case にすでに対応する switch の case がある場合でも、常にデフォルトの case を含める必要があります。@unknown 属性をデフォルトの case に適用でき、これは、デフォルトの case が将来追加される列挙型の case にのみ一致することを示します。デフォルトの case がコンパイラ時に知られている列挙型の case のいずれかに一致すると、Swift は警告を生成します。この将来の警告は、対応する switch の case がない列挙型にライブラリ作成者が新しい case を追加したことをあなたに知らせます。
以下の例では、Swift 標準ライブラリの Mirror.AncestorRepresentation 列挙型の既存の 3 つの case すべてを切り替えます。将来さらに case が追加されると、新しい case を考慮に入れるために switch 文を更新する必要があることを示す警告をコンパイラは生成します。
一致する case 内のコードが実行を終了した後、プログラムは switch 文から抜けます。プログラムの実行は継続せず、次の case、またはデフォルトの case に "fall through" しません。すなわち、一つの case から次へ実行を続けたい場合、明示的に fallthrough 文を含めると、それは単に fallthrough キーワードで構成されており、そこから実行を継続したい case に書きます。fallthrough 文の詳細は、下記の fallthrough 文 を参照してください。
ループ文、if 文、switch 文、または do 文に、その直後にコロン (:) が続くラベルの名前で構成された 文ラベル を接頭辞で付けることができます。break と continue 文に文ラベルを使用して、ループ文または switch 文のフロー制御をどのように変更したいかについて明示でき、この事は以下の Break 文 と、Continue 文 で議論しました。
ラベル付き文のスコープは、文ラベル以下の文の全体です。ラベル付き文を入れ子にすることができますが、それぞれの文ラベルの名前は unique (ただ一つ) でなければなりません。
詳細および、文のラベルを使用する例については、フロー制御 の章の ラベル付きの文 を参照してください。
制御転送文は、プログラム内のコードを無条件に、一つのコードから別のコードへとプログラムの制御を転送することによって、実行される順序を変更できます。Swift には、5つの制御転送文があります。break 文、 continue 文、fallthrough 文、return 文、及び throw 文です。
break 文は、ループ、if 文または switch 文のプログラムの実行を終了します。break 文は、break キーワードのみで構成でき、または以下に示すように、文ラベルの名が続く break キーワードで構成されます。
break
break <#label name#>
break 文は、文ラベルの名前が続く場合、そのラベルの名前が付いたループ、if 文や switch 文のプログラムの実行を終了します。
break 文に、文ラベルの名前が続かない場合には、switch 文またはそれが発生した、最も内側のループ文のプログラムの実行を終了します。if 文から抜け出すためには、ラベルなしの break 文は使用できません。
どちらの場合も、プログラム制御は、含まれるループまたは switch 文がある場合、それに続くコードの最初の行に転送されます。
break 文を使用する方法の例については、フロー制御 の章の Break および ラベル付きの文 を参照してください。
continue 文は、ループ文の現在の反復のプログラムの実行を終了しますが、ループ文の実行は停止しません。continue 文は、continue キーワードのみで構成できますが、以下に示すように、文ラベルの名前が続く continue キーワードで構成できます。
continue
continue <#label name#>
continue 文に、文ラベルの名前が続く場合は、そのラベルで名付けられたループ文の現在の反復のプログラムの実行を終了します。
continue 文に、文ラベルの名前が続かない場合は、それが発生した最も内側のループ文を囲む現在の反復のプログラムの実行を終了します。
どちらの場合も、プログラム制御はその後、ループ文を囲む条件に転送されます。
for 文では、ループの本体の実行後に増分 (インクリメント) 式が評価されるため、continue 文が実行された後に増分 (インクリメント) 式が評価されます。
continue 文を使用する方法の例については、フロー制御 の章の Continue と、ラベル付きの文 を参照してください。
fallthrough 文は、fallthrough キーワードで構成され、switch 文の case ブロックでのみ発生します。fallthrough 文は、プログラムの実行を switch 文の一つの case から次の case へと続行します。プログラムの実行は、 switch 文の制御式の値と case のラベルのパターンが一致しない場合でも、次の case に進みます。
fallthrough 文は、case のブロックの最後の文としてではなく、switch 文の中のどの場所にでも書くことができますが、最後の case のブロックでは使用できません。また、そのパターンが値の結合パターンを含んでいる場合にも、case のブロックに制御を転送することはできません。
switch 文に fallthrough 文を使用する方法の例については、 フロー制御 の章の 制御転送文 を参照してください。
return 文は、関数またはメソッド定義の本体で発生し、呼び出し元の関数やメソッドに、プログラム実行を戻します。プログラムの実行は、関数やメソッドの呼び出しの直後の点に続きます。
return 文は、return キーワードのみで構成されるか、または以下に示すように、式が続く return キーワードで構成されます。
return
return<#expression#>
return 文に式が続く場合、式の値は、呼び出し元の関数やメソッドに返されます。式の値が、関数やメソッドの宣言で宣言された戻り値の型の値と一致しない場合は、呼び出し元の関数やメソッドに返される前に、式の値は、戻り値の型に変換されます。
return 文に、式が続かない場合は、値を返さない関数やメソッドから戻るためにのみ使用できます (すなわち、関数やメソッドの戻り値の型が Void または ( ) の場合)。
throw 文は、throw する関数またはメソッドの本体、またはその型が throws キーワードでマークされたクロージャ式の本体で発生します。
throw 文を使用すると、プログラムは現在のスコープの実行を終了し、エラーの伝播を始めてそれが囲むスコープに伝播します。throw されたエラーは、do 文 の catch 句で処理されるまで伝播を続けます。
throw 文は、以下に示すように、throw キーワードとそれに続く式で構成されます。
throw <#expression#>
式 (expression) の値は、Error プロトコルに準拠した型を持たなければなりません。throw 文を含む do 文または関数が throw するエラーの型を宣言する場合、式の値はその型のインスタンスでなければなりません。
throw 文の使用例については、エラー処理 の章の throw 関数を使用したエラーの伝播 を参照してください。
defer 文は、プログラムの制御を defer 文が現れるスコープの外に転送する直前にコードの実行をするために使用されます。
defer 文の形式は以下のとおりです。
defer {
<#statements#>
}
defer 文内の文は、プログラム制御の転送方法に関係なく実行されます。例えば、ファイル記述子を閉じたり、エラーが throw された場合でも起こる必要があるアクションを実行したりなどの手動リソース管理を実行する場合などに、defer 文を使用できる事を意味します。
defer 文内の 文 は、defer 文を囲むスコープの最後で実行されます。
上記のコードでは、if 文内の defer は、関数 f で宣言された defer より前に実行されます。これは、if 文のスコープが関数のスコープよりも前に終了するためです。
複数の defer 文が同じスコープ内にある場合、それらの表示順序は実行される順序と逆です。与えられたスコープ内で最後の defer 文を最初に実行する事は、その最後の defer 文内の文は、他の defer 文によってクリーンアップされるだろうリソースを参照できる事を意味します。
defer 文内の文は、defer 文の外のプログラム制御を転送することはできません。
do 文は新しいスコープを導入するために使用され、定義されたエラー条件と一致するパターンを含む 1 つ以上の catch 句をオプションで含むことができます。do 文のスコープ内で宣言された変数と定数には、そのスコープ内でのみアクセスできます。
Swift の do 文は、コードブロックを区切るために使用される C の中括弧 ({}) に似ており、実行時にパフォーマンスコストが発生することはありません。
do 文の形式は以下のとおりです。
do {
try <#expression#>
<#statements#>
} catch <#pattern 1#> {
<#statements#>
} catch <#pattern 2#> where <#condition#> {
<#statements#>
} catch <#pattern 3#>, <#pattern 4#> where <#condition#> {
<#statements#>
} catch {
<#statements#>
}
do 文では、オプションで、throw するエラーの型を指定できます。その形式は以下のとおりです。
do 文に throws 句が含まれている場合、do ブロックは指定された 型 のエラーのみを throw できます。型 は、Error プロトコルに準拠する具体的な型、Error プロトコルに準拠する不透明型、またはボックス化されたプロトコル型の任意の Error でなければなりません。do 文が throw するエラーの型を指定しない場合、Swift は以下のようにエラーの型を推測します。
明示的な型を持つエラーの操作の詳細については、エラーの型の指定 を参照してください。
do コードブロック内のいずれかの文がエラーを throw した場合、プログラム制御は、そのパターンがエラーに一致する最初の catch 句に転送されます。どの句も一致しない場合、エラーは周囲のスコープに伝播します。エラーが最上位のレベルで処理されない場合、プログラムの実行は実行時エラーで停止します。
switch 文のように、コンパイラは、catch 句が網羅的かどうかを推測しようとします。このような判断ができる場合、そのエラーは処理されたものとみなされます。それ以外の場合、エラーは包含するスコープの外へと伝播する可能性があります。つまり、エラーは、それを囲む catch 句で処理されなければならないか、またはそれを含む関数は、throws で宣言されなければなりません。
複数のパターンを持つ catch 句は、そのパターンのいずれかがエラーに一致する場合、エラーに一致します。 catch 句に複数のパターンが含まれている場合、すべてのパターンに同じ定数または変数結束が含まれていなければならず、結束された各変数または定数は、catch 句のすべてのパターンで同じ型を持たなければなりません。
エラーが確実に処理されるためには、ワイルドカードパターン(_) のような、すべてのエラーに一致するパターンを持つ catch 句を使用して下さい。catch 句がパターンを指定していない場合、catch 句はすべてのエラーと一致し、error という名のローカル定数に結束されます。catch 句で使用できるパターンの詳細については、パターン を参照してください。
do 文といくつかの catch 句を使用する方法の例については、エラーの処理 を参照してください。
コンパイラ制御文によって、プログラムはコンパイラの動作の局面を変更できます。Swift には 3 つのコンパイラ制御文があります:条件コンパイルブロックと行制御文、コンパイル時診断文です。
条件コンパイルブロックは、1つ以上のコンパイル条件の値に応じて、条件付きでコードをコンパイルする事を可能にします。
すべての条件コンパイルブロックは、#if コンパイル指令で始まり #endif コンパイル指令で終わります。単純な条件コンパイルブロックは、以下の形式をとります。
#if <#compilation condition#>
<#statements#>
#endif
if 文の条件とは異なり、コンパイル条件 はコンパイル時に評価されます。結果として、コンパイル条件 がコンパイル時に true と評価された場合にのみ、文 はコンパイルされて実行されます。
コンパイル条件 には、true および false のブール値リテラル、-D コマンドラインフラグで使用される識別子、または以下の表にリストされているプラットフォーム条件のいずれかを含めることができます。
プラットフォーム条件 | 有効な引数 |
---|---|
os( ) | macOS, iOS, watchOS, tvOS, Linux, Windows |
arch( ) | i386, x86_64, arm, arm64 |
swift( ) | >= or < バージョン番号が続く |
compiler( ) | >= or < バージョン番号が続く |
canImport( ) | モジュール名 |
targetEnvironment( ) | simulator, macCatalyst |
swift( ) および compiler( ) プラットフォーム条件のバージョン番号は、メジャー番号、オプションのマイナー番号、オプションのパッチ番号などで構成され、バージョン番号の各部分はドット (.) で区切られています。比較演算子とバージョン番号の間には空白があってはいけません。compiler( ) のバージョンは、コンパイラに渡された Swift のバージョン設定に関係なく、コンパイラのバージョンです。swift( ) のバージョンは、現在コンパイルされている言語バージョンです。たとえば、Swift 5 コンパイラを使用して Swift 4.2 モードでコードをコンパイルした場合、コンパイラのバージョンは 5 であり、言語のバージョンは 4.2 です。これらの設定では、以下のコードは 3 つのメッセージすべてを出力します。
canImport( ) プラットフォーム条件の引数は、すべてのプラットフォームには存在しないかもしれないモジュールの名前です。モジュールの名前にはピリオド (.) を含めることができます。この条件は、モジュールをインポートできるかどうかをテストしますが、実際にはそれをインポートしません。モジュールが存在する場合、プラットフォーム条件は true を返し、それ以外の場合は false を返します。
targetEnvironment( ) プラットフォーム条件は、コードが特定の環境用にコンパイルされている場合 true を返します。それ以外の場合は false を返します。
論理演算子 &&、||、 および ! を使用してコンパイル条件を組み合わせたり無効にすることができ、グループ化には括弧を使用できます。これらの演算子は、通常のブール式を組み合わせるために使用される論理演算子と同じ結合性と優先順位を持ちます。
if 文と同様に、複数の条件分岐を追加して、異なるコンパイル条件をテストできます。#elseif 句を使用して、任意の数の追加分岐を追加できます。また、#else 句を使用して最後の追加分岐を追加することもできます。複数の分岐を含む条件コンパイルブロックの形式は以下のとおりです。
#if <#compilation condition 1#>
<#statements to compile if compilation condition 1 is true#>
#elseif <#compilation condition 2#>
<#statements to compile if compilation condition 2 is true#>
#else
<#statements to compile if both compilation conditions are false
#endif
明示的なメンバー式を条件付きコンパイルブロックで包み込む方法については、明示的なメンバ式 を参照してください。
行制御文は、コンパイルされているソースコードの行番号とファイル名とは異なる行番号とファイル名を指定するために使用されます。行制御文を使用して、診断とデバッグの目的で Swift が使用するソースコードの位置を変更します。
行制御文には、以下の形式があります。
#sourceLocation(file <#file path#>, line: <#line number#>)
#sourceLocation( )
行制御文の最初の形式は、行制御文が続くコード行で始まる #line,#file,#fileID および filePath のリテラル式の値を変更します。行番号 (line number) は #line の値を変更し、ゼロより大きい任意の整数リテラルです。ファイルパス (file path) は #file,#fileID および filePath の値を変更し、文字列リテラルです。指定された文字列が #filePath の値になり、文字列の最後のパス部分が #fileID の値によって使用されます。#file,#fileID, および #filePath については、リテラル式 を参照してください。
行制御文の2番目の形式、#sourceLocation( ) は、ソースコードの位置をデフォルトの行番号とファイルパスにリセットします。
Swift 5.9 以前では、#warning および #error 文はコンパイル中に診断を出力します。この動作は、Swift 標準ライブラリの warning(_:) および error(_:) マクロによって提供されるようになりました。
利用可能条件 は、指定されたプラットフォーム引数に基づいて、実行時に API の利用可能性を照会する if、while、 および guard 文の条件として使用されます。
利用可能条件の形式は以下のとおりです。
if #available(<#platform name#> <#version#>, <#...#>, *) {
<#statements to execute if the APIs are available#>
} else {
<#fallback statements to execute if the APIs are unavailable#>
}
利用可能件を使用して、使用したい API が実行時に使用可能かどうかに応じて、コードブロックを実行できます。コンパイラは、そのコードブロック内の API が使用可能であることを確認する時に、利用可能条件の情報を使用します。
利用可能条件には、プラットフォーム名とバージョンのコンマ区切りのリストが使用されます。iOS、macOS、watchOS、 および tvOS をプラットフォーム名に使用し、対応するバージョン番号を含めます。* 引数は必須で、他の全てのプラットフォームでは、利用可能条件によって保護されたコードブロックの本体が、ターゲットによって指定された最小のデプロイメント・ターゲットで実行されることを指定します。
ブール条件とは異なり、&& や || などの論理演算子を使用して利用可能条件を結合することはできません。! を使用する代わりに、利用可能条件を無効にするには、以下の形式の利用不可能条件を使用します。
if #unavailable(<#platform name#> <#version#>, <#...#>) {
<#fallback statements to execute if the APIs are unavailable#>
} else {
<#statements to execute if the APIs are available#>
}
#unavailable 形式は、条件を否定するシンタックスシュガーです。利用不可能な状態では、* 引数は暗黙的であり、含めることはできません。これは、利用可能条件の * 引数と同じ意味を持ちます。