union(直和型)
書ける形(8)
Section titled “書ける形(8)”| 書き方 | 説明 |
|---|---|
abstract record Shape; record Circle(float R) : Shape; | 宣言と値の生成 |
s switch { Circle c => ..., _ => ... } | 型による分岐 |
s switch { Circle c => ..., Rect r => ... } | 既定のケースを置かない分岐 |
A a => ..., B b => ..., C c => ... | 3 つ以上の型の分岐 |
s is Circle | 特定の型の判定 |
void Use(Shape s) | 引数での受け取り |
Shape Make() | 戻り値での返却 |
Shape[] all = new Shape[2]; | 配列の要素 |
書けない形(3)
Section titled “書けない形(3)”| 書き方 | 説明 | エラー | 理由 | 代わりに |
|---|---|---|---|---|
private Shape held; | フィールドに持つ | TUKI0001 | 未実装 | ローカル変数・引数・配列で受け渡す |
record Pair(Node L, Node R) : Node; | 自分自身を含む定義(再帰) | TUKI0001 | 環境 | 配列と添字で木を表す |
Debug.Log(s) | union の値をそのまま外へ渡す | TUKI0001 | 環境 | 先に型で分岐して、取り出した値を渡す |
| union の値はフィールドに持てません。状態として残すときは、種類を表す列挙型の値と、それぞれの中身を、別々のフィールドに置きます。 |
値型(struct / record)に付けたインタフェースも、これと同じ形に変換されます。どちらも、いま入っているのがどの型かを表す番号 1 つと、型ごとの置き場を並べたものになります。書き方が違うだけで、動く仕組みは同じです。Behaviour に付けたインタフェースだけは別の仕組みで、そちらは Behaviour そのものを指します。
型ごとの置き場は別々で、重ねません。union が使うスロットの数は、すべての型の中身を足した数に、種類を表す番号のぶんを加えたものになります。いちばん大きい型に合わせるのではありません。型を 1 つ増やすと、その型の中身のぶんだけ増えます(スロットの上限はUdon の実行モデル)。
宣言と値の生成
Section titled “宣言と値の生成”基底を abstract record で宣言し、それぞれの型を、その基底を継承する record で宣言します。
using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnDeclare : TsukimiBehaviour{ void Start() { Shape s = new Circle(1f); float a = s switch { Circle c => c.R, Rect r => r.W * r.H, _ => 0f, }; Debug.Log(a); // => 1 }}型による分岐
Section titled “型による分岐”using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnSwitchWithDefault : TsukimiBehaviour{ void Start() { Shape s = new Rect(2f, 3f); float a = s switch { Circle c => c.R, Rect r => r.W * r.H, _ => 0f, }; Debug.Log(a); // => 6 }}既定のケースを置かない分岐
Section titled “既定のケースを置かない分岐”ケースを尽くしていれば、既定のケースは要りません。
using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnSwitchExhaustive : TsukimiBehaviour{ void Start() { Shape s = new Circle(1f); float a = s switch { Circle c => c.R, Rect r => r.W * r.H, }; Debug.Log(a); // => 1 }}3 つ以上の型の分岐
Section titled “3 つ以上の型の分岐”using UnityEngine;using Tsukimi;
public abstract record Shape;public record A(int N) : Shape;public record B(int N) : Shape;public record C(int N) : Shape;
public class UnThreeCases : TsukimiBehaviour{ void Start() { Shape s = new A(1); int v = s switch { A a => a.N, B b => b.N, C c => c.N, _ => 0 }; Debug.Log(v); // => 1 }}特定の型の判定
Section titled “特定の型の判定”using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnIsPattern : TsukimiBehaviour{ void Start() { Shape s = new Circle(1f); bool isCircle = s is Circle; Debug.Log(isCircle); // => true }}引数での受け取り
Section titled “引数での受け取り”using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnParameter : TsukimiBehaviour{ void Start() { Use(new Circle(1f)); }
private void Use(Shape s) { float a = s switch { Circle c => c.R, Rect r => r.W * r.H, _ => 0f, }; Debug.Log(a); // => 1 }}戻り値での返却
Section titled “戻り値での返却”using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnReturnValue : TsukimiBehaviour{ void Start() { Shape s = Make(); float a = s switch { Circle c => c.R, Rect r => r.W * r.H, _ => 0f, }; Debug.Log(a); // => 1 }
private Shape Make() { return new Circle(1f); }}using UnityEngine;using Tsukimi;
public abstract record Shape;public record Circle(float R) : Shape;public record Rect(float W, float H) : Shape;
public class UnArray : TsukimiBehaviour{ void Start() { Shape[] all = new Shape[2]; all[0] = new Circle(1f); all[1] = new Rect(1f, 2f); float total = 0f; for (int i = 0; i < all.Length; i++) { Shape s = all[i]; float a = s switch { Circle c => c.R, Rect r => r.W * r.H, _ => 0f, }; total += a; } Debug.Log(total); // => 3 }}