nim的引用和指针
nim语言的引用和其他语言的指针有点相似
可以提供一种“多对一”的关系
这就意味着不同的引用可以指向同一个内存位置
nim区分可被追踪的引用和不可被追踪的引用
不可被追踪的引用又称为指针
可被追踪的引用可以被垃圾回收器回收
不可被追踪的引用指向手动分配的对象,或其他地方创建出来的一块内存区域
这也就是说,不可被追踪的引用是不安全的
对于某些底层操作,不可被追踪的引用有其存在的必要
可被追踪的引用使用ref关键字定义,
不可被追踪的引用使用ptr关键字定义
空下标的方括号[]可以用来解引用
addr方法可以返回一个实例的地址
对于一个地址来说,它始终是一个不可追踪的引用
所以addr方法也是一个不安全的方法。
.操作符和[]操作符可以隐式执行,先来看一下下面的代码
1 2 3 4 5 6 7 8 9 10 | type Node = ref NodeObj NodeObj = object le, ri: Node data: int var n: Node new(n) n.data = 9 |
在上面的代码中,不需要写成n[].data,
因为方括号操作符已经隐式执行了
事实上nim官方也强烈不建议写成n[].data
另外,自动解引用操作也直接作用于一个方法的调用
但目前看来,还必须加上{.experimental.}配置节
请看如下示例代码:
1 2 3 4 5 6 | {.experimental.} proc depth(x: NodeObj): int = ... var n: Node new(n) echo n.depth |
也不用写成n[].depth
为了简化类型检查,nim语言不支持递归元组
下面的写法是错误的
1 | type MyTuple = tuple [a: ref MyTuple] |
同样 T = ref T 也是错误的
如果一个对象只能出现其引用类型,不能出现其值类型
那么可以用如下方法完成:
1 2 3 4 | type Node = ref object le, ri: Node data: int |
可以使用内置的new方法为一个可被追踪的对象分配内存
可以使用alloc、dealloc和realloc来应对不可被追踪的对象
这些方法的具体信息都可以在system类库的说明文档中找到
如果一个引用指向为空,那么这个引用的值就是nil
如果你碰到一个不可被追踪的对象里面包含一个可被追踪的对象(或者是一个字符串、又或者是一个sequences)
那么就需要特别留意了,为了让一切都正常释放,
你必须在释放不可被追踪的对象之前,使用内置的GCunref方法处理一下这个对象的那些特殊属性
请看下面的示例代码:
1 2 3 4 5 6 7 8 9 10 | type Data = tuple [x, y: int , s: string] # 在内存堆上创建一个不可被追踪的对象: var d = cast[ptr Data](alloc0(sizeof(Data))) # create a new string on the garbage collected heap: d.s = "abc" # 告诉 GC 这个string类型的属性已经没有存在的必要了: GCunref(d.s) # 释放不可被追踪的对象: dealloc(d) |
如果不用GCunref方法处理一下对象的字符串属性,
那么这个字符串所占用的内存将永远不会被释放
上面的代码同时也展示了:
怎么获得一个类型的size
alloc0方法创建一个没有类型的指针
cast方法可以绕过类型系统,让指针具有类型ptr Data
只有在非常必要的时候再用cast方法,因为他会破坏类型安全,导致不可预知的BUG
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统