用一次载入的数据包去包装

问题描述:

我正在写一个邮政编码位置查找包,它从csv载入所有的英国邮政编码,我只想载入数据一次我想知道什么是最好的用Go来实现这一点。用一次载入的数据包去包装

type Location struct { 
    Latitude float64 
    Longitude float64 
} 

var postCodeCache = make(map[string]Location) 

这些是我的数据类型,目前我有一个名为LoadData和LookupPostCode()的函数。理想情况下,我想导入我的包,如果它尚未加载,它会自动加载数据。

你有两个选择:

  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它是一个可行的解决方案。 –

您可以使用init()函数在您的包来完成。

或者,如果频繁更改,您可以将CSV转换为单独的.go文件中的Go Map定义,并在编译时将其“加载”。