文と制御構文
対応(24)
Section titled “対応(24)”| 書き方 | 説明 | 注意 |
|---|---|---|
if / else | 条件による分岐 | |
switch (n) { case 1: ... } | 値による分岐(文) | |
n switch { 1 => 10, _ => 0 } | 値による分岐(式) | ケースが値を尽くしていても、int と列挙型では省けません。省けるのは union だけです。 |
n switch { var v when v > 0 => 10, _ => 0 } | 条件を付けたケース | switch 文の case には書けません。 |
n > 0 ? 10 : 20 | 条件演算子 | |
while (n < 3) | 条件が続く間の繰り返し | |
do { ... } while (n < 3); | 後判定の繰り返し | |
for (int i = 0; i < 3; i++) | 回数を決めた繰り返し | |
for (int i = 0, j = 3; i < j; i++, j--) | 複数の変数での繰り返し | |
foreach (int v in a) | 配列の走査 | 実行環境に列挙子が無いためです。 |
foreach (var (a, b) in ps) | 走査しながらの分解 | |
for { for { } } | ループの入れ子 | |
break | ループの脱出 | |
continue | 次の繰り返しへの継続 | |
while (true) { ... break; } | 無限ループの脱出 | 抜けるには本体の break が必要です。 |
if (...) { return; } | 途中の return | |
{ … } | ブロック | |
; | 何もしない文 | |
const int a = 1; | ローカル定数 | |
int Twice(int x) { return x * 2; } | ローカル関数 | 外の変数は読めますが、書き戻せません(非対応)。 |
static int Twice(int x) { … } | static なローカル関数 | |
for (;;) | for の 3 部の省略 | |
return; | 値を返さない return | |
class MyError : System.Exception { } | 例外の型の宣言 |
非対応(21)
Section titled “非対応(21)”| 書き方 | 説明 | エラー | 理由 | 代替 |
|---|---|---|---|---|
goto top; | ラベルへ飛ぶ | TUKI0001, TUKI0099 | 設計 | ループで書き直す |
goto case c; / goto default; | switch の別のケースへ飛ぶ | TUKI0001 | 設計 | 共通の処理をメソッドへ出して、両方の case から呼ぶ |
case 0: if (c) { break; } … | ケースの途中で抜ける | TUKI0001 | 未定 | 抜ける条件を反転し、残りをその条件の下に書く |
L: stmt | 文にラベルを付ける | TUKI0099 | 設計 | goto が無いので、ラベルを使わない形に書き直す |
throw new Exception(); | 例外を投げる | TUKI0001, TUKI0101 | 環境 | 戻り値や状態で失敗を表す |
try { } catch { } | 例外を受ける | TUKI0001 | 環境 | 事前に条件を確認する |
throw; | 捕まえた例外を投げ直す | TUKI0001 | 環境 | 戻り値や状態で失敗を表す |
catch (…) when (…) | 条件つきで例外を受ける | TUKI0001 | 環境 | 同上 |
try { } finally { } | 例外の有無によらず後始末を実行する | TUKI0001 | 環境 | 後始末をブロックの最後に書く |
using (r) { … } | ブロックを抜けるときに後始末する | TUKI0001 | 未実装 | 後始末のメソッドを自分で呼ぶ(finally が無いので、途中で抜けたときは実行されません) |
using var r = …; | 宣言した変数の後始末を任せる | TUKI0001, TUKI0099 | 未実装 | 同上 |
yield return / yield break | 少しずつ返す | TUKI0001 | 環境 | 配列に詰めて返す |
IEnumerator<int> Nums() | イテレータを返す | TUKI0001 | 環境 | 同上 |
p switch { (1, 2) => … } | ケースで位置ごとに分解する | TUKI0001 | 未実装 | { Item1: 1, Item2: 2 } と書くか、要素を読んでから比べる |
void Bump() { n = n + 1; }(外の変数へ書き戻す) | メソッドの中の関数から、外の変数を変更する | TUKI0001 | 未定 | 戻り値で返して、呼び出した側で代入する(値を読むだけの関数は書けます) |
ref int r = ref a; | 変数に別名を付ける | TUKI0001 | 未定 | 値を代入して使う |
lock (o) { … } | 排他制御をする | TUKI0001 | 環境 | スレッドが 1 本しか無いため不要 |
async Task Go() { await ...; } | 非同期に待つ | TUKI0001, TUKI0101 | 環境 | 時間をおいて呼び出す仕組みを使う |
async void Go() | 戻り値の無い非同期メソッドを書く | TUKI0001, TUKI0101 | 環境 | 同上 |
n switch { 1 => 10, 2 => 20 } | 既定のケースを置かずに分ける | TUKI0001 | 設計 | _ => を必ず置く。union に対してだけ省ける |
foreach (var (a, b) in ps)(Deconstruct を自分で書いた型) | 自分で書いた分解の手順を使う | TUKI0001 | 設計 | フィールドを名前で読む |
| 宣言と使用は別 | 宣言だけが対応していることは、使えることを意味しません。例外の型は宣言に対応していて、投げる行を書いた瞬間に初めてエラーになります |
分岐と繰り返し
Section titled “分岐と繰り返し”条件による分岐
Section titled “条件による分岐”using UnityEngine;using Tsukimi;
public class ExpressionsIfElse : TsukimiBehaviour{ void Start() { int n = 1; if (n > 0) { n = 2; } else { n = 3; } Debug.Log(n); // => 2 }}値による分岐(文)
Section titled “値による分岐(文)”using UnityEngine;using Tsukimi;
public class ExpressionsSwitchStatement : TsukimiBehaviour{ void Start() { int n = 1; switch (n) { case 1: n = 10; break; default: n = 0; break; } Debug.Log(n); // => 10 }}値による分岐(式)
Section titled “値による分岐(式)”_ => のケースが必要です。
using UnityEngine;using Tsukimi;
public class ExpressionsSwitchExpression : TsukimiBehaviour{ void Start() { int n = 1; int r = n switch { 1 => 10, _ => 0 }; Debug.Log(r); // => 10 }}条件を付けたケース
Section titled “条件を付けたケース”when を書くと、パターンに当たったうえで条件が真のときだけ、そのケースを選びます。
using UnityEngine;using Tsukimi;
public class ExpressionsSwitchArmWhen : TsukimiBehaviour{ void Start() { int n = 1; int r = n switch { var v when v > 0 => 10, _ => 0 }; Debug.Log(r); // => 10 }}using UnityEngine;using Tsukimi;
public class ExpressionsTernary : TsukimiBehaviour{ void Start() { int n = 1; int r = n > 0 ? 10 : 20; Debug.Log(r); // => 10 }}条件が続く間の繰り返し
Section titled “条件が続く間の繰り返し”using UnityEngine;using Tsukimi;
public class ExpressionsWhile : TsukimiBehaviour{ void Start() { int n = 0; while (n < 3) { n++; } Debug.Log(n); // => 3 }}後判定の繰り返し
Section titled “後判定の繰り返し”using UnityEngine;using Tsukimi;
public class ExpressionsDoWhile : TsukimiBehaviour{ void Start() { int n = 0; do { n++; } while (n < 3); Debug.Log(n); // => 3 }}回数を決めた繰り返し
Section titled “回数を決めた繰り返し”using UnityEngine;using Tsukimi;
public class ExpressionsFor : TsukimiBehaviour{ void Start() { int total = 0; for (int i = 0; i < 3; i++) { total += i; } Debug.Log(total); // => 3 }}複数の変数での繰り返し
Section titled “複数の変数での繰り返し”using UnityEngine;using Tsukimi;
public class ExpressionsForMultiInit : TsukimiBehaviour{ void Start() { int count = 0; for (int i = 0, j = 3; i < j; i++, j--) { count++; } Debug.Log(count); // => 2 }}foreach が回せるのは配列だけです。
using UnityEngine;using Tsukimi;
public class ExpressionsForeachArray : TsukimiBehaviour{ void Start() { int[] a = new int[] { 1, 2 }; int total = 0; foreach (int v in a) { total += v; } Debug.Log(total); // => 3 }}走査しながらの分解
Section titled “走査しながらの分解”using UnityEngine;using Tsukimi;
public class ExpressionsForeachDeconstruct : TsukimiBehaviour{ void Start() { (int, int)[] ps = { (1, 2) }; foreach (var (a, b) in ps) { Debug.Log(a + b); } // => 3 }}ループの入れ子
Section titled “ループの入れ子”using UnityEngine;using Tsukimi;
public class ExpressionsNestedLoop : TsukimiBehaviour{ void Start() { int count = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { count++; } } Debug.Log(count); // => 4 }}ループの脱出
Section titled “ループの脱出”using UnityEngine;using Tsukimi;
public class ExpressionsBreak : TsukimiBehaviour{ void Start() { int count = 0; for (int i = 0; i < 5; i++) { if (i == 2) { break; } count++; } Debug.Log(count); // => 2 }}次の繰り返しへの継続
Section titled “次の繰り返しへの継続”using UnityEngine;using Tsukimi;
public class ExpressionsContinue : TsukimiBehaviour{ void Start() { int count = 0; for (int i = 0; i < 5; i++) { if (i == 2) { continue; } count++; } Debug.Log(count); // => 4 }}無限ループの脱出
Section titled “無限ループの脱出”while (true) は条件を評価せずに回り続けます。
using UnityEngine;using Tsukimi;
public class ExpressionsWhileTrueBreak : TsukimiBehaviour{ void Start() { int n = 0; while (true) { n++; if (n > 2) { break; } } Debug.Log(n); // => 3 }}途中の return
Section titled “途中の return”using UnityEngine;using Tsukimi;
public class ExpressionsReturnEarly : TsukimiBehaviour{ private int Level() { return 1; }
void Start() { Debug.Log(1); // => 1 if (Level() > 0) { return; } Debug.Log(2); }}using UnityEngine;using Tsukimi;
public class StBlock : TsukimiBehaviour{ void Start() { { int a = 1; Debug.Log(a); // => 1 } }}何もしない文
Section titled “何もしない文”using UnityEngine;using Tsukimi;
public class StEmpty : TsukimiBehaviour{ void Start() { ; Debug.Log(1); // => 1 }}ローカル定数
Section titled “ローカル定数”using UnityEngine;using Tsukimi;
public class StLocalConst : TsukimiBehaviour{ void Start() { const int a = 1; Debug.Log(a); // => 1 }}ローカル関数
Section titled “ローカル関数”メソッドの中に関数を宣言できます。
using UnityEngine;using Tsukimi;
public class StLocalFunc : TsukimiBehaviour{ void Start() { int Twice(int x) { return x * 2; } Debug.Log(Twice(2)); // => 4 }}static なローカル関数
Section titled “static なローカル関数”using UnityEngine;using Tsukimi;
public class StLocalFuncStatic : TsukimiBehaviour{ void Start() { static int Twice(int x) { return x * 2; } Debug.Log(Twice(2)); // => 4 }}for の 3 部の省略
Section titled “for の 3 部の省略”using UnityEngine;using Tsukimi;
public class StForOmitted : TsukimiBehaviour{ void Start() { int i = 0; for (;;) { i++; if (i > 2) break; } Debug.Log(i); // => 3 }}値を返さない return
Section titled “値を返さない return”using UnityEngine;using Tsukimi;
public class StReturnVoid : TsukimiBehaviour{ void Start() { Debug.Log(1); // => 1 return; }}宣言のみ対応
Section titled “宣言のみ対応”例外の型の宣言
Section titled “例外の型の宣言”例外の型は宣言できますが、投げることも捕まえることもできません。
using UnityEngine;using Tsukimi;
public class MyError : System.Exception { }public class ExCustom : TsukimiBehaviour{ void Start() { Debug.Log(1); // => 1 }}