struct と record
書ける形(34)
Section titled “書ける形(34)”| 書き方 | 説明 |
|---|---|
struct Point { public int X; } | フィールド |
public Point(int x) | コンストラクタ |
public int Twice() | メソッド |
public int X { get; set; } | プロパティ |
public int X { get; init; } | init アクセサのプロパティ |
public int Twice { get { … } } | 計算するプロパティ |
public static int Zero() | 静的メソッド |
public static readonly int Zero = 0; | 静的な読み取り専用フィールド |
public static readonly Point Origin = new Point(); | 値が struct の静的な読み取り専用フィールド |
struct Outer { public Inner I; } | struct の入れ子 |
readonly struct Point | readonly struct |
ref struct Span | ref struct |
private Point held; | フィールドとして保持 |
public Point held; | 公開フィールドへの差し込み |
Point[] ps = new Point[2]; | 配列の要素 |
void Use(Point p) | 引数での受け取り |
Point Make() | 戻り値での返却 |
default(Point) | 既定値の生成 |
public static Point operator +(Point a, Point b) | 二項演算子の定義 |
operator +(M x, M y) | 加算の定義 |
operator == / operator != | 等値の定義 |
operator < / operator > | 大小の定義 |
operator !(M x) | 否定の定義 |
operator ++(M x) | 増分演算子の定義 |
operator <<(M x, int n) | シフト演算子の定義 |
operator true / operator false | true / false 演算子の定義 |
public class Holder { … } | 自作の参照型の宣言 |
record Tag(int N, string S); | 位置パラメータによる宣言 |
t with { N = 2 } | with 式 |
a == b | 値としての比較 |
(int n, int m) = t; | 分解 |
public int Twice() | record のメソッド |
record Leaf(int N) : Base; | 基底の record の継承 |
record Leaf(int N, int M) : Base(N); | 位置パラメータを持つ基底の継承 |
書けない形(7)
Section titled “書けない形(7)”| 書き方 | 説明 | エラー | 理由 | 代わりに |
|---|---|---|---|---|
public void Bump() { X++; } | this を書き換えるメソッド | TUKI0001 | 未実装 | 新しい値を返す形にする |
public static Point Current = new Point(); | 書き換えられる静的フィールド | TUKI0001 | 設計 | static readonly にする(変わる値は Behaviour のフィールドに置く) |
record Leaf(int A, int M) : Base(A); | 基底へ別の名前のパラメータを渡す | TUKI0001 | 未実装 | 基底のパラメータと同じ名前にそろえる(Base(N)) |
public int Twice { get { … } set { … } } | 書き換えられる計算プロパティ | TUKI0001 | 未実装 | get だけにするか、メソッドにする(値として複製されるので書き戻せない) |
new Holder()(class に対して) | 自分で作った参照型を生成する | TUKI0001 | 環境 | struct / record にする(値として扱われる) |
h.V = 1;(class の値に対して) | 自分で作った参照型のフィールドに書く | TUKI0001 | 環境 | 同上 |
Holder.Make()(class の静的メソッド) | 自分で作った参照型の静的メソッドを呼ぶ | TUKI0001 | 環境 | Behaviour のメソッドにするか、struct にする |
位置パラメータを持つ基底を継承するとき、基底へ渡せるのは同じ名前のパラメータそのものだけです。record Leaf(int N, int M) : Base(N); は通りますが、record Leaf(int A, int M) : Base(A); は通りません。派生の値は、基底のフィールドと自分のフィールドを平らに並べたもので、構築のときに名前でそれぞれの場所へ配るためです。 |
using UnityEngine;using Tsukimi;
public struct Point{ public int X; public int Y;}
public class SrDeclareFields : TsukimiBehaviour{ void Start() { Point p = new Point(); p.X = 1; Debug.Log(p.X + p.Y); // => 1 }}コンストラクタ
Section titled “コンストラクタ”using UnityEngine;using Tsukimi;
public struct Point{ public int X; public Point(int x) { X = x; }}
public class SrConstructor : TsukimiBehaviour{ void Start() { Point p = new Point(3); Debug.Log(p.X); // => 3 }}メソッドを書けます。this を書き換えるメソッドは書けません(書けない形)。
using UnityEngine;using Tsukimi;
public struct Point{ public int X; public int Twice() { return X * 2; }}
public class SrMethod : TsukimiBehaviour{ void Start() { Point p = new Point(); p.X = 2; Debug.Log(p.Twice()); // => 4 }}using UnityEngine;using Tsukimi;
public struct Point{ public int X { get; set; }}
public class SrProperty : TsukimiBehaviour{ void Start() { Point p = new Point(); p.X = 1; Debug.Log(p.X); // => 1 }}init アクセサのプロパティ
Section titled “init アクセサのプロパティ”using UnityEngine;using Tsukimi;
public struct Point{ public int X { get; init; }}
public class SrInitAccessor : TsukimiBehaviour{ void Start() { Point p = new Point { X = 1 }; Debug.Log(p.X); // => 1 }}計算するプロパティ
Section titled “計算するプロパティ”get だけなら書けます。set は書けません(書けない形)。
using UnityEngine;using Tsukimi;
public struct Point{ public int X; public int Twice { get { return X * 2; } }}
public class R_cps : TsukimiBehaviour{ void Start() { Point p = new Point(); p.X = 2; Debug.Log(p.Twice); // => 4 }}静的メソッド
Section titled “静的メソッド”using UnityEngine;using Tsukimi;
public struct Point{ public static int Zero() { return 0; }}
public class SrStaticMethod : TsukimiBehaviour{ void Start() { Debug.Log(Point.Zero()); // => 0 }}静的な読み取り専用フィールド
Section titled “静的な読み取り専用フィールド”using UnityEngine;using Tsukimi;
public struct Point{ public int X; public static readonly int Zero = 0;}
public class SrStaticReadonlyPrimitive : TsukimiBehaviour{ void Start() { Debug.Log(Point.Zero); // => 0 }}値が struct の静的な読み取り専用フィールド
Section titled “値が struct の静的な読み取り専用フィールド”自分で宣言した struct や record の値も持てます。書き換えられる静的フィールドは書けません(書けない形)。
using UnityEngine;using Tsukimi;
public struct Point{ public int X; public static readonly Point Origin = new Point();}
public class R_srsv : TsukimiBehaviour{ void Start() { Point p = Point.Origin; Debug.Log(p.X); // => 0 }}struct の入れ子
Section titled “struct の入れ子”struct のフィールドに、別の struct を持てます。
using UnityEngine;using Tsukimi;
public struct Inner{ public int V;}
public struct Outer{ public Inner I;}
public class SrNested : TsukimiBehaviour{ void Start() { Outer o = new Outer(); o.I.V = 1; Debug.Log(o.I.V); // => 1 }}readonly struct
Section titled “readonly struct”using UnityEngine;using Tsukimi;
public readonly struct Point{ public readonly int X; public Point(int x) { X = x; }}
public class SrReadonlyStruct : TsukimiBehaviour{ void Start() { Point p = new Point(1); Debug.Log(p.X); // => 1 }}ref struct
Section titled “ref struct”ref struct と宣言した型も、値として作って使えます。
using UnityEngine;using Tsukimi;
public ref struct Span{ public int X;}
public class SrRefStruct : TsukimiBehaviour{ void Start() { Span s = new Span(); s.X = 1; Debug.Log(s.X); // => 1 }}フィールドとして保持
Section titled “フィールドとして保持”Behaviour のフィールドとして持てます。
using UnityEngine;using Tsukimi;
public struct Point{ public int X;}
public class SrField : TsukimiBehaviour{ private Point held;
void Start() { held.X = 1; Debug.Log(held.X); // => 1 }}公開フィールドへの差し込み
Section titled “公開フィールドへの差し込み”public にすると、編集画面から値を設定できます。
using UnityEngine;using Tsukimi;
public struct Point{ public int X;}
public class SrPublicField : TsukimiBehaviour{ public Point held;
void Start() { Debug.Log(held.X); // => 0 }}using UnityEngine;using Tsukimi;
public struct Point{ public int X;}
public class SrArray : TsukimiBehaviour{ void Start() { Point[] ps = new Point[2]; ps[0].X = 1; Debug.Log(ps[0].X); // => 1 }}引数での受け取り
Section titled “引数での受け取り”引数には複製が渡るので、呼ばれた側で書き換えても呼び出し元の値は変わりません。
using UnityEngine;using Tsukimi;
public struct Point{ public int X;}
public class SrParameter : TsukimiBehaviour{ void Start() { Use(new Point()); }
private void Use(Point p) { Debug.Log(p.X); // => 0 }}戻り値での返却
Section titled “戻り値での返却”using UnityEngine;using Tsukimi;
public struct Point{ public int X;}
public class SrReturnValue : TsukimiBehaviour{ void Start() { Point p = Make(); Debug.Log(p.X); // => 0 }
private Point Make() { return new Point(); }}既定値の生成
Section titled “既定値の生成”using UnityEngine;using Tsukimi;
public struct Point{ public int X;}
public class SrDefaultValue : TsukimiBehaviour{ void Start() { Point p = default(Point); Debug.Log(p.X); // => 0 }}演算子の定義
Section titled “演算子の定義”二項演算子の定義
Section titled “二項演算子の定義”using UnityEngine;using Tsukimi;
public struct Point{ public int X; public static Point operator +(Point a, Point b) { Point r = new Point(); r.X = a.X + b.X; return r; }}
public class SrOperator : TsukimiBehaviour{ void Start() { Point a = new Point(); Point b = new Point(); Point c = a + b; Debug.Log(c.X); // => 0 }}using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static M operator +(M x, M y) { return new M(x.V + y.V); }}public class OpBinAdd : TsukimiBehaviour{ void Start() { M a = new M(1); M b = a + a; Debug.Log(b.V); // => 2 }}using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static bool operator ==(M x, M y) { return x.V == y.V; } public static bool operator !=(M x, M y) { return x.V != y.V; } public override bool Equals(object o) { return false; } public override int GetHashCode() { return 0; }}public class OpEqPair : TsukimiBehaviour{ void Start() { M a = new M(1); Debug.Log(a == a); // => true }}using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static bool operator <(M x, M y) { return x.V < y.V; } public static bool operator >(M x, M y) { return x.V > y.V; }}public class OpCmpPair : TsukimiBehaviour{ void Start() { M a = new M(1); Debug.Log(a < a); // => false }}using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static M operator !(M x) { return x; }}public class OpNot : TsukimiBehaviour{ void Start() { M a = new M(1); M b = !a; Debug.Log(b.V); // => 1 }}増分演算子の定義
Section titled “増分演算子の定義”using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static M operator ++(M x) { return new M(x.V + 1); }}public class OpInc : TsukimiBehaviour{ void Start() { M a = new M(1); a++; Debug.Log(a.V); // => 2 }}シフト演算子の定義
Section titled “シフト演算子の定義”using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static M operator <<(M x, int n) { return x; }}public class OpShift : TsukimiBehaviour{ void Start() { M a = new M(1); M b = a << 1; Debug.Log(b.V); // => 1 }}true / false 演算子の定義
Section titled “true / false 演算子の定義”using UnityEngine;using Tsukimi;
public struct M { public float V; public M(float v) { V = v; } public static bool operator true(M x) { return x.V > 0; } public static bool operator false(M x) { return x.V <= 0; }}public class OpTrueFalse : TsukimiBehaviour{ void Start() { M a = new M(1); if (a) { Debug.Log(1); } // => 1 }}class(宣言だけ)
Section titled “class(宣言だけ)”自作の参照型の宣言
Section titled “自作の参照型の宣言”宣言までは通りますが、使うと断られます(書けない形)。struct と record なら使えます。
using UnityEngine;using Tsukimi;
public class Holder { public int V; }public class C2Decl : TsukimiBehaviour{ void Start() { Debug.Log(1); // => 1 }}record
Section titled “record”位置パラメータによる宣言
Section titled “位置パラメータによる宣言”using UnityEngine;using Tsukimi;
public record Tag(int N, string S);
public class SrRecordPositional : TsukimiBehaviour{ void Start() { Tag t = new Tag(1, "a"); Debug.Log(t.N); // => 1 }}with 式
Section titled “with 式”using UnityEngine;using Tsukimi;
public record Tag(int N);
public class SrRecordWith : TsukimiBehaviour{ void Start() { Tag t = new Tag(1); Tag u = t with { N = 2 }; Debug.Log(u.N); // => 2 }}値としての比較
Section titled “値としての比較”using UnityEngine;using Tsukimi;
public record Tag(int N);
public class SrRecordEquality : TsukimiBehaviour{ void Start() { Tag a = new Tag(1); Tag b = new Tag(1); Debug.Log(a == b); // => true }}using UnityEngine;using Tsukimi;
public record Tag(int N, int M);
public class SrRecordDeconstruct : TsukimiBehaviour{ void Start() { Tag t = new Tag(1, 2); (int n, int m) = t; Debug.Log(n + m); // => 3 }}record のメソッド
Section titled “record のメソッド”using UnityEngine;using Tsukimi;
public record Tag(int N){ public int Twice() { return N * 2; }}
public class SrRecordMethod : TsukimiBehaviour{ void Start() { Tag t = new Tag(2); Debug.Log(t.Twice()); // => 4 }}基底の record の継承
Section titled “基底の record の継承”using UnityEngine;using Tsukimi;
public abstract record Base;public record Leaf(int N, int M) : Base;
public class SrRecordInherit : TsukimiBehaviour{ void Start() { Leaf l = new Leaf(1, 2); Debug.Log(l.N + l.M); // => 3 }}位置パラメータを持つ基底の継承
Section titled “位置パラメータを持つ基底の継承”基底が位置パラメータを持つ形も継承できます。基底へ渡せるのは、同じ名前のパラメータそのものだけです(書けない形)。
using UnityEngine;using Tsukimi;
public abstract record Base(int N);public record Leaf(int N, int M) : Base(N);
public class R_recpos : TsukimiBehaviour{ void Start() { Leaf l = new Leaf(1, 2); Debug.Log(l.M); // => 2 }}