2017-07-08 15 views
0

我正在寫一個郵政編碼位置查找包,它從csv載入所有的英國郵政編碼,我只想載入數據一次我想知道什麼是最好的用Go來實現這一點。用一次載入的數據包去包裝

type Location struct { 
    Latitude float64 
    Longitude float64 
} 

var postCodeCache = make(map[string]Location) 

這些是我的數據類型,目前我有一個名爲LoadData和LookupPostCode()的函數。理想情況下,我想導入我的包,如果它尚未加載,它會自動加載數據。

回答

0

你有兩個選擇:

  1. 最簡單的是在任何其他處理開始加載主數據。如果您讀取數據的概率非常高,並且沒有其他理由可以立即避免,那爲什麼不呢?

  2. 用sync.Once加載數據。喜歡的東西:

    var dataLoaded sync.Once 
    var data DataType = nil 
    
    func LookupPostCode(some_args) { 
        once.Do(func() { 
         data = LoadData(some_subset_of_some_args) 
        }) 
        // and here I know, that data are loaded 
    } 
    
+0

不是'sync.Once'是不必要的依賴嗎?數據不能簡單地在沒有加載的時候是'nil'而在加載時不會'nil'? –

+0

@ChronoKitsune快速瀏覽顯示,英國有175萬郵政編碼。在加載這些數據的時候,多個goroutines可能會調用'LookupPostCode'。如果沒有'sync.Once',他們會開始加載CSV。有了它,他們會在第一次通話結束時阻止。 – terinjokes

+0

@eaglejokes有意義,除非我想知道爲什麼查找函數在數據量很大時加載數據。根據選項1的一個可能更合理的想法是在包外部生成映射並使其與包的其餘部分一起加載。導入速度可能會很慢,但是每次導入包時,導入速度可能比從文件導入速度要快。當然,這是假定實現支持這種幅度的地圖文字...我不知道有任何限制,所以AFAIK它是一個可行的解決方案。 –

0

您可以使用init()函數在您的包來完成。

或者,如果頻繁更改,您可以將CSV轉換爲單獨的.go文件中的Go Map定義,並在編譯時將其「加載」。