You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何将函数参数设置为ReadOnly?

Unity函数参数的[ReadOnly]特性使用解析

核心结论

可以给函数传入的变量标记[ReadOnly],而且在Unity Native容器+Burst编译的场景下非常有必要,绝非多此一举。

你对默认参数传递的误区澄清

你提到“不使用ref关键字时参数默认是只读的”,这个理解不完全准确:

  • 对于普通值类型(比如int、自定义结构体),默认传值是复制一份副本,函数里修改副本不会影响原变量,但这只是“不影响外部”,并非强制函数内部不能修改副本;
  • 对于引用类型(比如普通C#类),默认传的是引用的副本,函数里依然可以修改对象的内部状态;
  • 而Unity的NativeList这类Native容器是值类型结构体,但内部持有关联的堆内存,默认传值时会复制结构体,但内部的内存引用还是指向同一块堆内存,这时候函数里如果修改NativeList的内容,会直接影响原变量的堆内存数据。

你的代码示例中[ReadOnly]的作用

看你给出的代码:

private void func1()
{
    var newList = new NativeList<int>(1024, Allocator.Temp);
    // 写入newList数据
    func2(newList);
}

// 需要支持Burst编译
[BurstCompile]
private static void func2([ReadOnly] NativeList<int> newList)
{
    // 仅对newList执行读取操作
}

这里的[ReadOnly]有三个关键作用:

  1. Burst编译优化:告诉Burst编译器这个NativeList只会被读取,不会被修改,Burst可以跳过不必要的线程安全检查(比如写入锁),生成更高效的机器码;
  2. 代码契约与防误操作:明确标记这个函数只会读取参数,禁止在函数内部编写修改NativeList的逻辑,编译器会直接报错,避免后续维护时的误修改;
  3. Unity线程安全保障:Native容器的安全系统会根据[ReadOnly]标记,允许该参数在多线程环境下被安全访问,不会触发读写冲突的异常。

额外补充

如果是普通的自定义结构体参数,标记[ReadOnly]同样会让编译器禁止在函数内部修改该结构体的成员变量,起到强制只读的作用;而普通C#引用类型参数,Unity的[ReadOnly]特性不会限制对对象内部状态的修改,这时候如果需要只读约束,通常会用只读接口或者自定义只读包装类。

内容的提问来源于stack exchange,提问作者Swtsvn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:43:13