我有一個參數類型爲interface{}
的函數。這個參數代表我的模板數據。所以在每個頁面上它存儲不同的數據類型(主要是結構)。我想附加一些數據到這個參數的數據,但它是一個interface{}
類型,我不能這樣做。如何通過引用設置接口{}參數?
這是我的嘗試:
func LoadTemplate(templateData interface) {
appendCustomData(&templateData)
... //other functionality that is not relevant
}
func appendCustomData(dst interface{}) {
// ValueOf to enter reflect-land
dstPtrValue := reflect.ValueOf(dst)
// need the type to create a value
dstPtrType := dstPtrValue.Type()
// *T -> T, crashes if not a ptr
dstType := dstPtrType.Elem()
// the *dst in *dst = zero
dstValue := reflect.Indirect(dstPtrValue)
// the zero in *dst = zero
zeroValue := reflect.Zero(dstType)
// the = in *dst = 0
v := reflect.ValueOf(dst).Elem().Elem().FieldByName("HeaderCSS")
if v.IsValid() {
v = reflect.ValueOf("new header css value")
}
reflect.ValueOf(dst).Elem().Elem().FieldByName("HeaderCSS").Set(reflect.ValueOf(v))
//dstValue.Set(zeroValue)
fmt.Println("new dstValue: ", dstValue)
}
我能順利拿到"HeaderCSS"
值。但我無法用另一個價值取代它。我究竟做錯了什麼?
我templateData看起來是這樣的:
我有一個通用的結構:
type TemplateData struct {
FooterJS template.HTML
HeaderJS template.HTML
HeaderCSS template.HTML
//and some more
}
,我有另一種結構,如:
type pageStruct struct {
TemplateData //extends the previous struct
Form template.HTML
// and some other maps/string
}
我送這第二個結構作爲templateData論據。
現在我得到這個錯誤:
"reflect.Value.Set using unaddressable value" at the line: reflect.ValueOf(dst).Elem().Elem().FieldByName("HeaderCSS").Set(reflect.ValueOf(v))
的代碼從上面從這個答案的啓發:https://stackoverflow.com/a/26824071/1564840
我希望能夠從這個界面添加/編輯值。任何想法我怎麼能做到這一點?謝謝。
看來,如果你知道實際類型:只需鍵入assert到該類型並執行此類型支持的任何操作。如果不是:您必須顯示完整的代碼。順便說一句:擺脫空的'interface {}',你的代碼會更簡單。 – Volker
我不能只刪除接口{},因爲在每個頁面上參數類型會有所不同。 interface {}是允許我接受所有類型參數的選項。 – Pascut
這已經得到了很好的回答,但我想建議你可能應該添加一個'SetHeaderCSS'方法並傳入指定該方法的HeaderCSSSetter接口。這將通過簡單的更改消除所有反射*,從而爲您提供更好的性能,更好的可讀性和編譯時類型安全性。 – Adrian