2012-11-09 10 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

ファイナライザについてはゴーランナッツにdiscussionがありました。今の

  • 何のファイナライザ機能(編集:なし信頼性のファイナライザ機能、ニックで私に示されたように)が存在しない
  • GC使用していないと維持しませんが、任意の参照カウント

したがって、インスタンス数を自分で管理する必要があります。

通常、インスタンスは存在しないため、多くの実用的な用途(複合体のプロファイリングや理解しにくいプログラムは含まれません)では、deferを使用して変数の寿命を追跡できます。私はファイナライザの代わりにこのふりをするつもりはありませんが、それは単純で、しばしば十分です。

関連する問題