コンテンツにスキップ

struct と record

書き方説明
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 Pointreadonly struct
ref struct Spanref 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 falsetrue / 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);位置パラメータを持つ基底の継承
書き方説明エラー理由代わりに
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
}
}
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
}
}
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
}
}

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
}
}
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 のフィールドに、別の 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
}
}
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 と宣言した型も、値として作って使えます。

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
}
}

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
}
}

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
}
}

引数には複製が渡るので、呼ばれた側で書き換えても呼び出し元の値は変わりません。

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
}
}
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();
}
}
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
}
}
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
}
}
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
}
}
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
}
}
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
}
}

宣言までは通りますが、使うと断られます(書けない形)。structrecord なら使えます。

using UnityEngine;
using Tsukimi;
public class Holder { public int V; }
public class C2Decl : TsukimiBehaviour
{
void Start()
{
Debug.Log(1); // => 1
}
}
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
}
}
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
}
}
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
}
}
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
}
}
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
}
}