VOOZH about

URL: https://read01.com/yyA5e.html

⇱ nim的引用和指針 - 壹讀


Sunday, Apr 12, 2026

nim的引用和指針

2015/08/28 來源:cnblogs

nim語言的引用和其他語言的指針有點相似

可以提供一種「多對一」的關係

這就意味著不同的引用可以指向同一個內存位置

nim區分可被追蹤的引用和不可被追蹤的引用

不可被追蹤的引用又稱為指針

可被追蹤的引用可以被垃圾回收器回收

不可被追蹤的引用指向手動分配的對象,或其他地方創建出來的一塊內存區域

這也就是說,不可被追蹤的引用是不安全的

對於某些底層操作,不可被追蹤的引用有其存在的必要

可被追蹤的引用使用ref關鍵字定義,

不可被追蹤的引用使用ptr關鍵字定義

空下標的方括號可以用來解引用

addr方法可以返回一個實例的地址

對於一個地址來說,它始終是一個不可追蹤的引用

所以addr方法也是一個不安全的方法。

.操作符和操作符可以隱式執行,先來看一下下面的代碼

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.}配置節

請看如下示例代碼:

{.experimental.} proc depth(x: NodeObj): int = ... var n: Node new(n) echo n.depth

也不用寫成n.depth

為了簡化類型檢查,nim語言不支持遞歸元組

下面的寫法是錯誤的

type MyTuple = tuple[a: ref MyTuple]

同樣 T = ref T 也是錯誤的

如果一個對象只能出現其引用類型,不能出現其值類型

那麼可以用如下方法完成:

type Node = ref object le, ri: Node data: int

可以使用內置的new方法為一個可被追蹤的對象分配內存

可以使用alloc、dealloc和realloc來應對不可被追蹤的對象

這些方法的具體信息都可以在system類庫的說明文檔中找到

如果一個引用指向為空,那麼這個引用的值就是nil

如果你碰到一個不可被追蹤的對象裡面包含一個可被追蹤的對象(或者是一個字符串、又或者是一個sequences)

那麼就需要特別留意了,為了讓一切都正常釋放,

你必須在釋放不可被追蹤的對象之前,使用內置的GCunref方法處理一下這個對象的那些特殊屬性

請看下面的示例代碼:

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

您可能感興趣
免責聲明:本文內容來源于cnblogs,文章觀點不代表壹讀立場,如若侵犯到您的權益,或涉不實謠言,敬請向我們提出檢舉
最新文章 / 服務條款 / 私隱保護 / DMCA / 聯絡我們

壹讀/READ01.COM