2010-12-21 24 views
50

Ben Golang yeni am yapısına bir nil işaretçi panik.başlatmak için nasıl üye

başka bir fonksiyonu kullanılarak ve onu arayarak etrafında çalıştık

sağ new() sonra:

func (m *SyncMap) Init() { 
     m.hm = make(map[string]string) 
     m.lock = new(sync.RWMutex) 
} 

Ama bu mümkün olmazsa, acaba bu klişe seçin Başlatma kurtulmak için?

cevap

63

Sadece bir kurucuya ihtiyacınız var. Yaygın bir kullanılan desen daha fazla yapı içindeki alanlar, arka uç olarak bir goroutine başlayan veya bu yapıcı yapılacağının bir sonlandırıcı herşeyi kayıt durumunda

func NewSyncMap() *SyncMap { 
    return &SyncMap{hm: make(map[string]string)} 
} 

olduğunu.

func NewSyncMap() *SyncMap { 
    sm := SyncMap{ 
     hm: make(map[string]string), 
     foo: "Bar", 
    } 

    runtime.SetFinalizer(sm, (*SyncMap).stop) 

    go sm.backend() 

    return &sm 
} 
+1

Çok teşekkürler! Şimdi hatırlıyorum, öğreticide kurucu hakkında bir şey vardı, ama, bir Java müthiş, ben yeni operatör ile ilgili olması gerektiğini düşündüm, yeni değil ... kod kuralı –

+1

Bu işe yaramaz, ama en iyi tavsiye değildir. RWMutex bir işaretçi olarak değil, bir değer olarak dahil edilmelidir. Sıfır değeri kullanıma hazır bir mutekstir ve bu şekilde açık bir yapıcı işlevinden kaçınabilirsiniz. – kelnos

+0

Sadece bir örnek olduğundan farklı isimler almalıydı. Göreceğiniz gibi, orijinal yapının parçası olmayan 'foo' alanını da başlatıyorum. ;) – Mue

9

Mutex başlatılmadığından 'Mue' çözümü işe yaramıyor. Aşağıdaki modifikasyon çalışır:

package main 

import "sync" 

type SyncMap struct { 
     lock *sync.RWMutex 
     hm map[string]string 
} 

func NewSyncMap() *SyncMap { 
     return &SyncMap{lock: new(sync.RWMutex), hm: make(map[string]string)} 
} 

func (m *SyncMap) Put (k, v string) { 
     m.lock.Lock() 
     defer m.lock.Unlock() 
     m.hm[k] = v 
} 

func main() { 
    sm := NewSyncMap() 
    sm.Put("Test", "Test") 
} 

http://play.golang.org/p/n-jQKWtEy5

+0

Neden "sync.RWMutex" için bir işaretçi kullandınız? – Danilo

+0

Çok teşekkür ederim! Başlatılmamış muteks, hata ayıklaması çok zor olan ince bir hatayla sonuçlanır. Lock() ve Unlock() çağrıları başarılı olur, ancak erişim senkronize edilmez. – Steve

5

İyi yakalamak deamon tarafından. Mue muhtemelen kilidin bir işaretçi yerine bir değer olarak dahil edilmesinin daha yaygın modelini düşünüyordu. Muteks'in sıfır değeri kullanıma hazır bir kilitli Mutex olduğundan, hiçbir başlatma gerektirmez ve bir değer olarak yaygın olanı içerir. Daha fazla basitleştirme olarak, alan adını ihmal ederek gömebilirsiniz. Yapınız daha sonra Mutex'in yöntem kümesini elde eder. Bu çalışma örneğine bakın, http://play.golang.org/p/faO9six-Qx. Ayrıca defer kullanımını çıkardım. Bir dereceye kadar bir tercih ve kodlama tarzı meselesidir, fakat küçük bir yüke sahip olduğundan, özellikle koşullu kod yoksa, küçük işlevlerde kullanmama eğilimindedir.

İlgili konular