2012-11-09 60 views
8

在面向對象的語言中,我使用類變量來跟蹤當前有多少實例是通過構建時遞增和在銷燬時遞減來產生的。如何跟蹤一個類型實例的數量?

我嘗試實施中去類似的行爲:

package entity 

type Entity struct { 
    Name string 
} 

func New(name string) Entity { 
    entity := Entity{name} 
    counter++ 
    return entity 
} 

var counter int = 0 

func (e *Entity) Count() int { 
    return counter 
} 

和工程,我不能遞減通過析構函數的反一半。

我可以以某種方式模仿對象的破壞嗎? 我將如何正確跟蹤實例計數?

+0

是否有內置的方法來顯示對象的引用計數? –

回答

9

您可以這樣使用runtime.SetFinalizer。遊樂場版本見here

package main 

import (
    "fmt" 
    "runtime" 
) 

type Entity struct { 
    Name string 
} 

var counter int = 0 

func New(name string) Entity { 
    entity := Entity{name} 
    counter++ 
    runtime.SetFinalizer(&entity, func(_ *Entity) { 
     counter-- 
    }) 
    return entity 
} 

func (e *Entity) Count() int { 
    return counter 
} 

func main() { 
    e := New("Sausage") 
    fmt.Println("Entities", counter, e) 
    e = New("Potato") 
    fmt.Println("Entities", counter, e) 
    runtime.GC() 
    fmt.Println("Entities", counter) 
    e = New("Leek") 
    fmt.Println("Entities", counter) 
    runtime.GC() 
    fmt.Println("Entities", counter) 
} 

這將打印

Entities 1 {Sausage} 
Entities 2 {Potato} 
Entities 0 
Entities 1 
Entities 0 

從文檔註釋本作的陷阱與終結

x的終結定於某個任意時間x 變得無法訪問後運行。不能保證在程序退出前終結器將運行 ,因此通常它們僅在 長時間運行的程序期間釋放與對象關聯的非內存資源時纔有用。

+0

+1我錯了,因爲我沒有看到這個新功能 –

5

關於終結者的golang堅果有discussion

現在,

  • 沒有終結函數(編輯:沒有可靠的終結功能,給我看了由Nick)
  • GC無法使用和不維護任何引用計數

所以,你必須管理你的實例數自己。

通常情況下,您沒有自己生活的實例,因此對於許多實際應用(不包括複雜且難以理解的程序的分析),您可以使用defer來跟蹤變量的生命週期結束。我不會假裝這真的取代了終結者,但它很簡單,而且往往足夠。

相關問題