活學活用golang的反射機制

2021-10-01 01:26:41 字數 2366 閱讀 8910

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

我們知道intfloat64可以相互強制轉換,但是reflect.set()方法並不想幫你轉。

這裡還是要利用reflect包的兩個方法,type.convertibleto(u type)用來判斷能否轉換到指定型別,再通過value.convert(t type)來進行型別轉換。

再次優化我們的函式:

// 遍歷struct並且自動進行賦值

func structbyreflect(data map[string]inte***ce{}, instructptr inte***ce{}) else

// 遍歷結構體

for i := 0; i < rtype.numfield(); i++ else else

}} else

}}

在f.set()之前,先檢查data的type和struct欄位的type是否一致,如果不一致則進行轉換。

這樣功能就全部完成了,示例**中遇到錯誤都直接丟擲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 這種方法,感覺之前大家用的比...