您现在的位置是:首页 >技术教程 >Unity中值类型和引用类型及使用时的注意事项网站首页技术教程

Unity中值类型和引用类型及使用时的注意事项

dzj2021 2023-06-08 04:00:04
简介Unity中值类型和引用类型及使用时的注意事项

什么是值类型,什么是引用类型,Unity中值类型有哪些,引用类型有哪些,使用时需要注意些什么?

一、值类型和引用类型的概念

  • A. 值类型
    值类型是指变量直接存储其值的数据类型,变量的值被保存在栈中,每个变量都有自己的内存空间,它们不与其他变量共享。值类型包括基本数据类型(如 int、float、bool 等)和结构体(如 Vector3、Quaternion 等)。

  • B. 引用类型
    引用类型是指变量存储对象的引用(即指向对象的内存地址)的数据类型,变量的值被保存在堆中,多个变量可以引用同一个对象,它们共享对象的内存空间。引用类型包括类、接口、委托、数组等。

  • C. 额外信息:值传递和引用传递

(1)值传递是指将变量的值复制一份传递给函数或方法的参数,函数或方法内部对参数进行修改不会影响原始变量。比喻:主任让医生给10个人看病,值传递就是10个人已经在门口等待了,医生只需要按照顺序一个一个地诊断和治疗,不需要知道这些病人的身份信息。

(2)引用传递是指将变量的引用(即内存地址)传递给函数或方法的参数,函数或方法内部对参数进行修改会影响原始变量。比喻:引用传递就是给你10个人的身份证信息,你可以根据身份证信息来叫号,这样你可以直接找到对应的病人并对他们进行治疗。

值传递和引用传递在编程中都有自己的应用场景,需要根据具体情况选择合适的传递方式。

二、值类型和引用类型的区别

值类型引用类型
存储变量直接存储其值变量存储对象的引用
存储位置
独立性多个变量独立,不会相互影响多个变量可以引用同一个对象
包括基本数据类型和结构体类、接口、委托、数组等
传递值传递引用传递
复制赋值操作会复制变量的值赋值操作会复制引用,指向同一对象
内存管理由编译器自动管理需要手动管理内存,否则可能出现内存泄漏

三、Unity 中常见的值类型和引用类型

A. 值类型

  1. bool
  2. char
  3. int
  4. float
  5. double
  6. struct
    B. 引用类型
  7. string
  8. object
  9. class
  10. interface
  11. delegate
  12. 数组
  13. List
  14. Dictionary
  15. GameObject
  16. Component
  17. Transform
  18. 等等

四、值类型和引用类型在 Unity 中的使用注意事项

A. 值类型

1、值类型在 foreach中使用时的注意事项
在 foreach中使用值类型时,需要注意它们是按值传递的,即每次迭代都会复制一份值。这可能会导致性能问题,尤其是在迭代大量值类型时。为了避免这种情况,可以将值类型转换为引用类型,或者使用索引访问数组,这样可以避免复制值。

2、值类型在 Linq 的 ForEach 方法中使用时的注意事项
在 Linq 的 ForEach 方法中使用值类型时,也需要注意值类型是按值传递的,因此每次迭代都会复制一份值。为了避免这种情况,可以使用 Select 方法将值类型转换为引用类型,或者使用 Linq 的 Select 和 ToArray 方法将值类型转换为数组。

B. 引用类型

1、引用类型在 foreach中使用时的注意事项
在 foreach中使用引用类型时,需要注意它们是按引用传递的,即每次迭代都会使用同一个对象。这可能会导致意外的修改,尤其是在多个迭代器访问同一个集合时。为了避免这种情况,可以使用 ToArray 方法将集合转换为数组,这样就可以创建一个新的数组,而不是使用同一个集合。

2、引用类型在 Linq 的 ForEach 方法中使用时的注意事项
在 Linq 的 ForEach 方法中使用引用类型时,也需要注意引用类型是按引用传递的。为了避免意外的修改,可以使用 ToArray 方法将集合转换为数组,或者使用 Linq 的 Select 和 ToArray 方法将集合中的对象复制到一个新的数组中。

3、避免空引用异常
在使用引用类型时,需要注意对象是否已被销毁,以免出现空引用的情况。

C、如何用一种有效的方法来读写值类型和引用类型的列表或者数组

  • 迭代的时候,用下标
  • 同时满足单线程和多线程
  • 可读,可写
  • 单线程模式:
// 获取列表的下标集合,使用lambda表达式将列表中每个元素的下标返回为集合中的元素
List<int> indices = list.Select((item, index) => index).ToList();

// 对下标集合进行循环处理,对于每个下标,根据其在列表中的位置获取对应的元素值,并输出下标和元素值
indices.ForEach(index =>
{
    string value = list[index];
    //list[index] = ...
    Console.WriteLine($"Index: {index}, Value: {value}");
});

plinq的多线程模式:

// 创建一个包含字符串元素的列表
List<string> list = new List<string> { "apple", "banana", "orange", "pear" };

// 创建一个索引集合,用于访问列表中的元素
List<int> indices = Enumerable.Range(0, list.Count).ToList();

// 使用预先生成的索引集合,在并行处理列表时访问列表中的元素
indices.AsParallel().ForAll(index =>
{
    string item = list[index];
    Console.WriteLine($"Index: {index}, Value: {item}");
});

五、总结

值类型适用于存储简单的数据类型,如整数、浮点数和布尔值等。它们通常在栈上分配内存,并且具有较小的内存占用和较高的访问速度。

引用类型适用于存储复杂的数据类型,如类、数组和字符串等。它们通常在堆上分配内存,并且具有较大的内存占用和较慢的访问速度。引用类型允许对象在内存中动态分配和释放,因此更适合存储动态数据,如游戏中的角色和物体等。

如何用一种方法来实现快速的读写呢?

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。