1. 程式人生 > >[Nim] object的構造與析構

[Nim] object的構造與析構

在現代的程式語言當中,在設計時幾乎都拋棄了建構函式與解構函式,比如像Go、Rust等。但在實際開發中我們確實又需要這個特性,今天學習一下如何曲線救國。

我們先看看new的三使用方法

第一種:通過型別構造

type
    Person = object
        x: int

var
    obj1 = new(Person)
    obj2: ref Person

obj1.x = 5
echo obj1.addr.repr

obj2 = obj1
obj2.x = 10
echo obj1.x # 10

Person是非引用型別的,但是通過new(T)後,返回的是引用型別

第二種:通過變數構造

type
    Person = object
        x: int

var
    obj1: ref Person
    obj2: ref Person

new(obj1)
obj1.x = 5
echo obj1.addr.repr

obj2 = obj1
obj2.x = 10
echo obj1.x # 10

通過變數構造要求變數型別是必須是ref的,否則編譯報錯。

第三種:指定解構函式

這種方式支援傳遞一個析構回撥函式,回撥函式簽名為"proc (x: ref T)"

type
    Person = ref object
        p: pointer

proc free(this: Person) =
    dealloc(this.p)
    echo "byte"

proc builder(): Person =
    new(result, free)
    result.p = alloc(5)

var obj = builder()
echo obj.addr.repr
obj = nil        # 讓obj變為垃圾
GC_fullCollect() # 手動呼叫垃圾收集

如果要支援析構,則在new的時候必須通過new(var)的方式去建立。

析構是有了,可構造呢?這個就沒有辦法了,只能寫一個普通方法當建構函式,需要手動呼叫,在實踐中一般通過factory,builder去構造例項,比如上面的例子可以改為

type
    Person = ref object
        p: pointer

# 建構函式
proc init(this: Person) =
    this.p = alloc(5)

# 解構函式
proc free(this: Person) =
    dealloc(this.p)
    echo "byte"

# 構造器
proc builder(): Person =
    new(result, free)
    result.init

# 呼叫
var obj = builder() # 通過構造器建立例項,不要自己手動new
echo obj.addr.repr
obj = nil        # 讓obj變為垃圾
GC_fullCollect() # 手動呼叫垃圾收集