コンテンツにスキップ

パターン

書き方説明
switch (n) { case 1: … }文による分岐
case 1:文による分岐(数値)
n switch { 1 => 10, _ => 0 }式による分岐
m switch { Mode.A => 1, _ => 0 }列挙型による分岐
s switch { "a" => 1, _ => 0 }文字列による分岐
s is Dot型の判定
s is Line l型の判定と束縛
case Dot:case ラベルの型
s switch { Dot d => …, Line l => … }union のケースの網羅
n is 1定数との照合
s is nullnull との照合
s is "a"文字列の定数との照合
m is Mode.On列挙型の定数との照合
n is < 30大小の照合
n is >= 0 and <= 100条件の組み合わせ(連言)
Next() is >= 0 and <= 100受け手の評価回数
n is 3 or 4条件の組み合わせ(選言)
s is not null否定
n is int and (< 0 or > 100)括弧による優先順位
n is var x常に成立する束縛
h is { V: 1 }メンバの値との照合
h is { V: > 0 }メンバの値の入れ子の照合
k switch { < 30 => … }ケースの大小
k switch { 3 or 4 => … }ケースの選言
k switch { int n when n > 3 => … }ケースの条件(when)
n switch { var v when v > 0 => … }束縛してからの条件
書き方説明エラー理由代わりに
p is (1, 2)分解して位置で照合するTUKI0001未実装メンバの値で照合する({ Item1: 1 }
value is int(型引数の値に対して)型引数の値にパターンを当てるTUKI0001未実装型引数を使わない形に書き換える
case int n when n > 3:case に条件を付けるTUKI0099未実装switch の式ならケースに条件を書ける(k switch { int n when n > 3 => … }
s switch { Line l when … => … }union の型パターンに条件を付けるTUKI0001未実装条件をケースの本体へ移すか、when を使わずケースを分ける
n switch { 1 => 10, 2 => 20 }既定のケースを省く(intTUKI0001設計_ => を置く。union に対してだけ省ける
m switch { Mode.A => 1, Mode.B => 2 }既定のケースを省く(列挙型)TUKI0001設計ケースを尽くしても省けない
既定のケースを省けるのは union のときだけです。int と列挙型では、ケースを尽くしても _ => のケースが要ります。

when を書けるのは switch の式のケースだけです。case ラベルに when を付けると TUKI0099 が出ます。

using UnityEngine;
using Tsukimi;
public class PatSwitchStatement : TsukimiBehaviour
{
void Start()
{
int n = 1;
switch (n)
{
case 1: Debug.Log(10); break;
default: Debug.Log(0); break;
}
}
}
// 出力
// 10
using UnityEngine;
using Tsukimi;
public class IsoSwStmtConst : TsukimiBehaviour
{
void Start()
{
int k = 1;
switch (k) { case 1: Debug.Log(1); break; default: Debug.Log(0); break; } // => 1
}
}

switch の式は、一致したケースの値を結果にします。int を照合するときは _ => のケースが要ります。

using UnityEngine;
using Tsukimi;
public class PatDiscardArm : TsukimiBehaviour
{
void Start()
{
int n = 1;
int r = n switch { 1 => 10, _ => 0 };
Debug.Log(r); // => 10
}
}

列挙型の定数をケースに書けます。ケースを尽くしても _ => のケースは省けません。

using UnityEngine;
using Tsukimi;
public enum Mode { A, B }
public class PatEnumConstant : TsukimiBehaviour
{
void Start()
{
Mode m = Mode.A;
int r = m switch { Mode.A => 1, _ => 0 };
Debug.Log(r); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PatStringConstant : TsukimiBehaviour
{
void Start()
{
string s = "a";
int r = s switch { "a" => 1, _ => 0 };
Debug.Log(r); // => 1
}
}

is の右に型を書く形は、union とインタフェースの値に対してだけ使えます。

using UnityEngine;
using Tsukimi;
public abstract record Shape;
public record Dot : Shape;
public record Line(int Len) : Shape;
public class IsoIsTypeUnion : TsukimiBehaviour
{
void Start()
{
Shape s = new Dot();
bool b = s is Dot;
Debug.Log(b); // => true
}
}
using UnityEngine;
using Tsukimi;
public abstract record Shape;
public record Dot : Shape;
public record Line(int Len) : Shape;
public class PtDeclaration : TsukimiBehaviour
{
void Start()
{
Shape s = new Line(3);
if (s is Line l) { Debug.Log(l.Len); } // => 3
}
}

case ラベルにも型を書けます。union の値を型で分岐する形です。

using UnityEngine;
using Tsukimi;
public abstract record Shape;
public record Dot : Shape;
public record Line(int Len) : Shape;
public class PtTypeCase : TsukimiBehaviour
{
void Start()
{
Shape s = new Dot();
switch (s) { case Dot: Debug.Log(0); break; default: Debug.Log(1); break; } // => 0
}
}

union のケースをすべて書けば、_ => のケースを省けます。

using UnityEngine;
using Tsukimi;
public abstract record Shape;
public record Dot : Shape;
public record Line(int Len) : Shape;
public class PtExhaustiveUnion : TsukimiBehaviour
{
void Start()
{
Shape s = new Dot();
int v = s switch { Dot d => 0, Line l => l.Len };
Debug.Log(v); // => 0
}
}
using UnityEngine;
using Tsukimi;
public class IsoIsConst : TsukimiBehaviour
{
void Start()
{
int k = 1;
bool b = k is 1;
Debug.Log(b); // => true
}
}
using UnityEngine;
using Tsukimi;
public class PtConstNull : TsukimiBehaviour
{
void Start()
{
string s = null;
if (s is null) { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PtConstString : TsukimiBehaviour
{
void Start()
{
string s = "a";
if (s is "a") { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public enum Mode { Off, On }
public class PtConstEnum : TsukimiBehaviour
{
void Start()
{
Mode m = Mode.On;
if (m is Mode.On) { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PtRelational : TsukimiBehaviour
{
void Start()
{
int k = 1;
if (k is < 30) { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PtAnd : TsukimiBehaviour
{
void Start()
{
int k = 1;
if (k is >= 0 and <= 100) { Debug.Log(1); } // => 1
}
}

is の左は 1 度しか評価されません。条件を 2 つ書いても、Next() の呼び出しは 1 回です。

using UnityEngine;
using Tsukimi;
public class PtAndOnce : TsukimiBehaviour
{
int Next()
{
Debug.Log(9); // => 9
return 1;
}
void Start()
{
if (Next() is >= 0 and <= 100) { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PtOr : TsukimiBehaviour
{
void Start()
{
int k = 3;
if (k is 3 or 4) { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PtNot : TsukimiBehaviour
{
void Start()
{
string s = "a";
if (s is not null) { Debug.Log(1); } // => 1
}
}
using UnityEngine;
using Tsukimi;
public class PtParen : TsukimiBehaviour
{
void Start()
{
int k = 1;
if (k is int and (< 0 or > 100)) { Debug.Log(1); }
}
}
using UnityEngine;
using Tsukimi;
public class PtVar : TsukimiBehaviour
{
void Start()
{
int k = 1;
if (k is var x) { Debug.Log(x); } // => 1
}
}

{ } の中に、メンバの名前と照合する値を書きます。左に置けるのは、自分で宣言した structrecord だけです。

using UnityEngine;
using Tsukimi;
public struct Holder { public int V { get; set; } }
public class PtProperty : TsukimiBehaviour
{
void Start()
{
Holder h = new Holder();
if (h is { V: 1 }) { Debug.Log(1); }
}
}
using UnityEngine;
using Tsukimi;
public struct Holder { public int V { get; set; } }
public class PtNested : TsukimiBehaviour
{
void Start()
{
Holder h = new Holder();
if (h is { V: > 0 }) { Debug.Log(1); }
}
}
using UnityEngine;
using Tsukimi;
public class IsoSwExprRel : TsukimiBehaviour
{
void Start()
{
int k = 1;
int v = k switch { < 30 => 1, _ => 0 };
Debug.Log(v); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class IsoSwExprOr : TsukimiBehaviour
{
void Start()
{
int k = 3;
int v = k switch { 3 or 4 => 1, _ => 0 };
Debug.Log(v); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class IsoSwExprWhen : TsukimiBehaviour
{
void Start()
{
int k = 5;
int v = k switch { int n when n > 3 => n, _ => 0 };
Debug.Log(v); // => 5
}
}
using UnityEngine;
using Tsukimi;
public class R_wc : TsukimiBehaviour
{
void Start()
{
int n = 1;
int r = n switch { var v when v > 0 => 10, _ => 0 };
Debug.Log(r); // => 10
}
}