【C#基础】unity中结构体的使用

news/2024/11/16 14:55:18/

【C#基础】unity中结构体的使用

结构体(Struct)是值类型数据结构,在栈上分配内存,可以包含字段,属性,方法,构造函数。结构体可以实现接口,但是不能继承。在Dots里有大量依靠Struct实现接口来定义Entities数据类型和实现逻辑。

一、结构体的基本使用

  • 定义结构体
  • 结构体初始化
  • 结构体方法
  • 结构体扩展方法

1.定义结构体

结构体一般用于小型的数据类型,下面定义一个双精度的三维坐标数据为例。

Public struct DoubleVec {}

2.结构体初始化

(1)通常通过构造函数对结构体进行初始化,也可以单独定义后赋值。

结构体

public struct DoubleVec
{public double x;public double y;public double z;//构造函数public DoubleVec(double x, double y, double z){this.x = x;this.y = y;this.z = z;}
}

初始化和单独赋值

    DoubleVec doubleVec1;DoubleVec doubleVec2;void Start(){doubleVec1 = new DoubleVec(1, 1, 1);doubleVec2.x = 3;Debug.Log("doubleVec1.x=" + doubleVec1.x);Debug.Log("doubleVec2.x=" + doubleVec2.x);}

结果

doubleVec1.x=1
doubleVec2.x=3    

(2)没有对结构体进行初始化或者赋值,直接调用结构体的字段

重新定义一个字段类型多的结构体

public struct DoubleVec
{public float x;public float y;public double z;public string name;public Vector3 vec;public bool bo;public int[] ints;
}

直接使用字段

    DoubleVec doubleVec2;void Start(){Debug.Log("doubleVec2.y=" + doubleVec2.y);Debug.Log("doubleVec2.vec=" + doubleVec2.vec);Debug.Log("doubleVec2.name=" + doubleVec2.name);Debug.Log("doubleVec2.ints=" + doubleVec2.ints);Debug.Log("doubleVec2.bo=" + doubleVec2.bo);Debug.Log("doubleVec2.x=" + doubleVec2.x);}

结果

    doubleVec2.y=0 //浮点类型初始为0doubleVec2.vec=(0.00, 0.00, 0.00)//vecter初始为原点doubleVec2.name= //字符串为空doubleVec2.ints= //数组为空doubleVec2.bo=False   //bool为falsedoubleVec2.x=0

(3)构造函数

实例构造函数:初始化字段信息,构造函数参数必须对没有字段进行赋值

静态构造函数:当结构体构造实例时,静态构造函数会自动调用一次;不带任何参数,不带修饰符。

public struct DoubleVec
{public double x;public double y;public double z;//构造函数public DoubleVec(double x, double y, double z){this.x = x;this.y = y;this.z = z;}//静态构造函数static DoubleVec(){Debug.Log("被调用");}
}

3.结构体方法

  • get方法
  • 结构体传参方法
  • 逻辑运算

(1)get方法

可以直接在结构体变量后使用,下面以求模长为例

   DoubleVec doubleVec1;void Start(){doubleVec1 = new DoubleVec(1, 1, 1);//这里直接可以点出方法double mag= doubleVec1.Magnitude;Debug.Log("mag=" + mag);}

创建的方法

public struct DoubleVec
{public double x;public double y;public double z;//构造函数public DoubleVec(double x, double y, double z){this.x = x;this.y = y;this.z = z;}//必须用get方法给方法赋值public double Magnitude {get {return  magnitude(); }}//求模长的方法double magnitude(){double a = getLength(x, y);double b = getLength(a, z);return b;double getLength(double a, double b){return Math.Sqrt(a * a + b * b);}}
}

该方法只能使用结构体变量的字段进行逻辑处理,与结构体的字段关联

(2)结构体传参方法

可以在结构类型后面点出方法,传入参数进行逻辑处理,同样以求模长为例

  DoubleVec doubleVec1;void Start(){doubleVec1 = new DoubleVec(1, 1, 1);//这里是同结构体类型点出方法,参数为结构体变量double mag= DoubleVec.MagnitudeVec(doubleVec1);Debug.Log("mag=" + mag);}

创建方法

public struct DoubleVec
{public double x;public double y;public double z;//构造函数public DoubleVec(double x, double y, double z){this.x = x;this.y = y;this.z = z;}//这里要用静态方法,参数与结构体本身的字段没有关系public static double MagnitudeVec(DoubleVec vec){ return magnitude(vec);}//运算方法也要静态static double magnitude(DoubleVec vec){double a = getLength(vec.x, vec.y);double b = getLength(a, vec.z);return b;double getLength(double a, double b){return Math.Sqrt(a * a + b * b);}}
}

这种方法是很独立的,与结构体本身没有关联,只能算逻辑上的分类

(3)逻辑运算

这里的逻辑运算包括:加、减、乘、除、大于、小于、等于、不等于等。下面以实现加法为例。

    DoubleVec doubleVec1;DoubleVec doubleVec2;void Start(){doubleVec1 = new DoubleVec(1, 1, 1);doubleVec2 = new DoubleVec(2, 2, 2);DoubleVec doubleVec3 = doubleVec1 + doubleVec2;}

创建方法

public struct DoubleVec
{public double x;public double y;public double z;//构造函数public DoubleVec(double x, double y, double z){this.x = x;this.y = y;this.z = z;}//使用operator运算符重载方法//参数中必须有一个为DoubleVecpublic static DoubleVec operator +(DoubleVec a, DoubleVec b){return new DoubleVec(a.x + b.x, a.y + b.y, a.z + b.z);}
}

(4)operator 运算符的用法

一元运算符

一个参变量,直接跟变量使用

   //operator +public static DoubleVec operator +(DoubleVec a){return new DoubleVec(a.x , a.y , a.z );}//operator -public static DoubleVec operator -(DoubleVec a){return new DoubleVec(-a.x , -a.y , -a.z );}//operator ++public static DoubleVec operator ++(DoubleVec a){return new DoubleVec(a.x+1 , a.y+1 , a.z+1 );}//operator --public static DoubleVec operator --(DoubleVec a){return new DoubleVec(a.x-1 , a.y-1 , a.z-1 );}//operator !public static bool operator !(DoubleVec a){return true;}

使用方法

        doubleVec1 = new DoubleVec(1, 1, 1);DoubleVec doubleVec3 = - doubleVec1;//对应operator +doubleVec3 = +doubleVec1;//对应operator -doubleVec3 = doubleVec1++;//对应operator ++doubleVec3 = doubleVec1--;//对应operator --bool bo = !doubleVec1;//对应operator !

二元运算符

需要两个变量进行运算

   //operator +public static DoubleVec operator +(DoubleVec a, DoubleVec b){return new DoubleVec(a.x + b.x, a.y + b.y, a.z + b.z);}//也允许其中一个变量不是结构体的类型public static DoubleVec operator +(DoubleVec a, double b){return new DoubleVec(a.x + b, a.y + b, a.z + b);}//operator -public static DoubleVec operator -(DoubleVec a, DoubleVec b){return new DoubleVec(a.x - b.x, a.y - b.y, a.z - b.z);}//operator *public static DoubleVec operator *(DoubleVec a, double b){return new DoubleVec(a.x * b, a.y * b, a.z * b);}//operator /public static DoubleVec operator /(DoubleVec a, double b){return new DoubleVec(a.x / b, a.y / b, a.z / b);}

使用方法

        doubleVec1 = new DoubleVec(1, 1, 1);doubleVec2 = new DoubleVec(2, 2, 2);DoubleVec doubleVec3 =  doubleVec1;doubleVec3 = doubleVec1 + doubleVec2;//对应operator +doubleVec3 = doubleVec1 - doubleVec2;//对应operator -doubleVec3 = doubleVec1 + 1;//对应operator +doubleVec3 = doubleVec1 * 1;//对应operator*doubleVec3 = doubleVec1 / 1;//对应operator/

比较运算符

两个变量进行比较

  //operator == 
public static bool operator == (DoubleVec a, DoubleVec b){if (a.x==b.x&& a.y==b.y&&a.z==b.z){return true;}else{return false;}}//operator != public static bool operator !=(DoubleVec a, DoubleVec b){if (a.x != b.x && a.y!= b.y && a.z != b.z){return true;}else{return false;}}//operator >public static bool operator >(DoubleVec a, DoubleVec b){double magA = a.magnitude();double magB = b.magnitude();if (magA> magB){return true;}else{return false;}}//operator <public static bool operator <(DoubleVec a, DoubleVec b){double magA = a.magnitude();double magB = b.magnitude();if (magA < magB){return true;}else{return false;}}//operator >=public static bool operator >= (DoubleVec a, DoubleVec b){double magA = a.magnitude();double magB = b.magnitude();if (magA >= magB){return true;}else{return false;}}//operator <=public static bool operator <= (DoubleVec a, DoubleVec b){double magA = a.magnitude();double magB = b.magnitude();if (magA <= magB){return true;}else{return false;}}

使用方法

        bool _bool = doubleVec1 == doubleVec2;_bool = doubleVec1 != doubleVec2;_bool = doubleVec1 > doubleVec2;_bool = doubleVec1 < doubleVec2;_bool = doubleVec1 <= doubleVec2;_bool = doubleVec1 >= doubleVec2;

4.扩展方法

扩展方法可以是对unity中的类,密封类和结构体中的方法进行扩展。也可以对自己创建的结构体和类进行扩展,不过感觉很多余。

创建没有继承的静态类

public static class LearnExtention 
{
}

添加静态扩展方法,第一个参数用this修饰,类型为需要扩展的类型,后面为需要扩展的发方法所需要的参数。

///对上文的结构体进行扩展,求单位向量
public static class LearnExtention 
{public static DoubleVec normalized(this DoubleVec doubleVec){return doubleVec / doubleVec.Magnitude;}
}

使用方法

   doubleVec1 = new DoubleVec(2, 2, 2);
//在类型的变量后点出方法使用doubleVec2 = doubleVec1.normalized();
//因为方法为静态的,所以可以直接使用doubleVec2 = LearnExtention.normalized(doubleVec1);

http://www.ppmy.cn/news/1052886.html

相关文章

二分查找(Binary Search)及常见的具体实现(C++和Python)

二分查找&#xff08;Binary Search&#xff09;及常见的具体实现(C和Python) 二分查找是一种在有序数组中查找特定元素的算法。它通过将目标值与数组中间元素进行比较&#xff0c;从而排除掉一半的元素。如果目标值小于中间元素&#xff0c;则在数组的左半部分继续查找&#x…

STM32f103c6t6/STM32f103c8t6寄存器开发

目录 资料 寻址区 2区 TIMx RTC WWDG IWDG SPI I2S USART I2C USB全速设备寄存器 bxCAN BKP PWR DAC ADC ​编辑 EXTI ​编辑 GPIO AFIO SDIO DMA CRC RCC FSMC USB_OTG ETH&#xff08;以太网&#xff09; 7区 配置流程 外部中断 硬件中断 例子 点灯 …

论文阅读:DIN-SQL: Decomposed In-Context Learning of Text-to-SQL withSelf-Correction

NL2SQL是将自然语言转化为SQL的任务&#xff0c;该任务隶属于NLP的子任务&#xff0c;NL2SQL在AIGC时代之前&#xff0c;以seq2seq、BERT等系列的模型在NL2SQL的主流数据集上取得了不错的效果&#xff0c;2022年底&#xff0c;ChatGPT爆火&#xff0c;凭借LLM强大的逻辑推理、上…

机器学习深度学习——NLP实战(自然语言推断——注意力机制实现)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——NLP实战&#xff08;自然语言推断——数据集&#xff09; &#x1f4da;订阅专栏&#xff1a;机器学习&…

Centos 解决 XXX不在 sudoers 文件中。此事将被报告。的错误

本来想使用 sudo 拷贝一个文件&#xff0c;结果出现上面的问题&#xff01; 下面是解决方法&#xff1a; 首先登录root&#xff0c;然后执行下面的命令 vim /etc/sudoers 将你需要添加的用户带红色框线的地方&#xff0c;模仿root写一遍&#xff0c;然后保存&#xff01; …

[保研/考研机试] KY196 复数集合 北京邮电大学复试上机题 C++实现

题目链接&#xff1a; 复数集合_牛客题霸_牛客网 一个复数&#xff08;xiy&#xff09;集合&#xff0c;两种操作作用在该集合上&#xff1a; 1、Pop 表示读出集。题目来自【牛客题霸】https://www.nowcoder.com/share/jump/437195121692724009060 描述 一个复数&#xff08;…

【vue】el-table 数据更新后,刷新表格数据

表格里面的数据更新后&#xff0c;可以通过以下方法来刷新表格 方法1 用更新后的数据&#xff0c;覆盖之前的数据 var newTableData[];for(var i0;i<that.tableData.length;i){ if(aIdthat.selectStationId&&bIdthat.selectDeviceId){that.tableData[i].physica…

android 上拉固定高度显示,下拉关闭View BottomSheetDialog

具体代码 复制使用 1,新建一个BottomBaseStationDialogLayout.java类继承BottomSheetDialogFragment public class BottomBaseStationDialogLayout extends BottomSheetDialogFragment { public static BottomBaseStationDialogLayout getInstance() {return new BottomBase…