2014-11-25 22 views
5

Tôi đang làm việc trên dự án Go thực sự đầu tiên của mình và đã tìm kiếm một số công cụ để xử lý cấu hình.Cấu hình nâng cao với golang Viper lib

Cuối cùng, tôi đã tìm thấy công cụ này: https://github.com/spf13/viper đó là thật sự tốt đẹp nhưng tôi có một số vấn đề khi tôi cố gắng để xử lý một số cấu hình phức tạp hơn như ví dụ config.yaml sau:

app: 
    name: "project-name" 
    version 1 

models: 
    modelA: 
    varA: "foo" 
    varB: "bar" 

    modelB: 
    varA: "baz" 
    varB: "qux" 
    varC: "norf" 

tôi don 't biết làm thế nào để có được các giá trị từ modelB ví dụ. Trong khi xem mã lib, tôi đã tìm thấy những điều sau đây nhưng tôi không thực sự hiểu cách sử dụng nó:

// Marshals the config into a Struct 
func Marshal(rawVal interface{}) error {...} 

func AllSettings() map[string]interface{} {...} 

Điều tôi muốn là có thể, từ mọi nơi trong gói của tôi, để làm điều gì đó như :

modelsConf := viper.Get("models") 
fmt.Println(modelsConf["modelA"]["varA"]) 

Ai đó có thể giải thích cho tôi cách tốt nhất để đạt được điều này?

+1

Tất cả phụ thuộc nếu dữ liệu của bạn là phù hợp. Nếu tất cả các mô hình chỉ chứa varA và varB, tại sao bạn sẽ tạo một thực thể mới được gọi là modelA (và modelB)? Nhưng nếu modelB chứa varA, varB và varC, thì bạn phải làm một cái gì đó hoàn toàn khác. – Dippo

+0

Trong thực tế, modelB cũng sẽ có thể chứa một varC, tôi đã cập nhật ví dụ trong câu hỏi ban đầu của tôi –

+1

Hãy xem [link] này (http://golang.org/pkg/encoding/json/#example_RawMessage) – Dippo

Trả lời

7

Kể từ khi "mô hình" khối là một bản đồ, đó là một chút dễ dàng hơn để gọi

m := viper.GetStringMap("models") 

m sẽ là một bản đồ [chuỗi] giao diện {}

Sau đó, bạn nhận được giá trị của m [key], đó là một giao diện {}, vì vậy bạn cast nó để lập bản đồ [giao diện {}] giao diện {}:

m := v.GetStringMap("models") 
mm := m["modelA"].(map[interface{}]interface{}) 

Bây giờ bạn có thể truy cập vào "Vara" chìa khóa đi qua phím như một giao diện {}:

mmm := mm[string("varA")] 

mmm là foo

0

Bạn chỉ có thể sử dụng:

m := viper.Get("models.modelA")

hoặc

newViperForModelA := viper.Sub("models").Sub("modelA")

Các vấn đề liên quan