2017-05-08 52 views
-2

編輯:我不問如何正確初始化變量。我在問如何阻止它們被初始化不正確,以便採用該類型的函數不必顯式驗證它們的參數。如何防止Go中導出類型的初始化?

在走,我有一個包含地圖,如類型:

package foo 

type Bar struct { 
    baz map[string]int 
    total int 
} 

func NewBar() *Bar { 
    return &Bar{baz: map[string]int{}} 
} 

func (b *Bar) IncrementBaz(key string) { 
    f.baz[key] = f.baz[key] + 1 
    f.total++ 
} 

// ... 

如果另一個包初始化類型,然後試圖寫它,它會嘗試寫一個零地圖,引起了段錯誤:

package main 

import "foo" 

func main() { 
    var b foo.Bar 
    b.IncrementBaz("some_key") // write to nil map -> segfault 
    // ... 
} 

爲了防止這種情況,我希望把它使其他包無法初始化一個空foo.Bar

我不能簡單地將它取消導出,因爲我希望其他包中的函數能夠將它聲明爲參數或返回類型。如果我在一個接口把它包起來,我得到了類似的問題:

package "foo" 

type Bar interface { 
    IncrementBaz(string) 
    // ... 
} 

type bar struct { 
    baz map[string]int 
    total int 
} 

func NewBar() Bar { 
    return &bar{baz: map[string]int{}} 
} 

func (b *bar) IncrementBaz(key string) { 
    f.baz[key] = f.baz[key] + 1 
    f.total++ 
} 

// ... 

類似的問題:

package main 

import "foo" 

func main() { 
    var b foo.Bar 
    b.IncrementBaz("some_key") // method call on nil interface -> segfault 
    // ... 
} 

有什麼辦法有隻包聲明它可以初始化它的出口型?

回答

0

現在foo.Bar只是一個接口類型。默認值是一個零指針。你非常接近,只是將它初始化爲b := foo.NewBar()

+0

接口類型可以是'nil',這意味着任何接受此類型的函數都必須對其進行無檢查或冒險嘗試調用其方法時冒着恐慌,這是我想要避免的。 –