var data = map[string]inte***ce{}type fruit struct
func newfruit(data map[string]inte***ce{}) *fruit
return &s
}func main()
這樣實現簡單快速,但也有缺點:
是否有更好的解決方法,自動遍歷struct物件,並進行賦值呢?
首先想到for...range操作符,但golang裡range無法對結構體進行遍歷。
(如果只需遍歷struct而不用賦值,可以嘗試邪道組合:json.marshal()
和json.unmarshal()
一鍵把struct轉成map[string]inte***ce()
)
實際上要遍歷乙個struct,需要使用golang的reflect包。關於golang的反射機制不再贅述,可以參考go的文件,有很詳細的說明。
那麼現在利用reflect,嘗試改進之前的**
var data = map[string]inte***ce{}編譯執行type fruit struct
// 遍歷struct並且自動進行賦值
func structbyreflect(data map[string]inte***ce{}, instructptr inte***ce{}) else
// 遍歷結構體
for i := 0; i < rtype.numfield(); i++ else
}}func main()
structbyreflect(data, &fruit)
log.println("fruit:", fruit)
}
> panic: id not found
新的問題出現了,結構體的欄位名id
和data中的id
大小寫不一致,導致無法從data中取得對應的資料。
修改data的key name,或者修改struct的field name當然可以解決,但在實際應用中,data往往從外部獲得不受控制,而data的key通常也不符合go的命名規範,因此暴力改名不可取。
那怎麼解決呢?這裡可以利用go的成員變數標籤(field tag),給struct的字段增加額外的元資料,用以指定對應的欄位名。golang對json和xml等的序列化處理也是用了這個方法。
type fruit struct再次編譯執行,這次得到了期望的結果// 遍歷struct並且自動進行賦值
func structbyreflect(data map[string]inte***ce{}, instructptr inte***ce{}) else
// 遍歷結構體
for i := 0; i < rtype.numfield(); i++ else
}}
到這裡已經基本實現了想要的功能,但還有乙個問題,如果data中的資料型別,和struct中定義的型別稍有不一致,反射賦值語句就會報錯,
var data = map[string]inte***ce{}測試一下:
> panic: reflect.set: value of type int is not assignable to type float64
我們知道int
和float64
可以相互強制轉換,但是reflect.set()
方法並不想幫你轉。
這裡還是要利用reflect包的兩個方法,type.convertibleto(u type)
用來判斷能否轉換到指定型別,再通過value.convert(t type)
來進行型別轉換。
再次優化我們的函式:
// 遍歷struct並且自動進行賦值在f.set()之前,先檢查data的type和struct欄位的type是否一致,如果不一致則進行轉換。func structbyreflect(data map[string]inte***ce{}, instructptr inte***ce{}) else
// 遍歷結構體
for i := 0; i < rtype.numfield(); i++ else else
}} else
}}
這樣功能就全部完成了,示例**中遇到錯誤都直接丟擲panic,可以根據實際專案進行調整。
主要到這裡沒有處理巢狀的結構體等情況,這部分通過判斷type為struct時,進行遞迴處理就可以實現。
協程的活學活用(一)
之前寫協程的時候偶爾會遇到一些物體被關了沒有啟用,掛載上面的指令碼開啟的協程也不執行了。為了徹底解決這個問題,我聽取同事建議寫了這個工具指令碼,當然你也可以嘗試協程單例或者其他模式的。主要目的就是讓協程都在乙個固定不刪除的物體上同一開啟和停止。namespace toolsbylm private ...
golang的反射機制
首先,golang反射,分為 t reflect.typeof n num t.numfield t reflect.typeof n num t.field n int 從0開始,以宣告的順序排序type students struct func stu students t func stu s...
活學活用,CSS清除浮動的4種方法
清除浮動這個問題,做前端的應該再熟悉不過了,咱是個新人,所以還是記個筆記,做個積累,努力學習向大神靠近。css清除浮動的方法網上一搜,大概有n多種,用過幾種,說下個人感受。1 結尾處加空div標籤clear both12 34.div1 left right clear 這種方法,感覺之前大家用的比...