91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang?reflect反射如何使用

發布時間:2023-04-14 11:47:14 來源:億速云 閱讀:87 作者:iii 欄目:開發技術

這篇文章主要介紹“Golang reflect反射如何使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Golang reflect反射如何使用”文章能幫助大家解決問題。

    首先有一段以下結構體的定義

    type User struct {
    	UserName string
    	UserId   int `name:"uid"`
    }

    初始化一個結構體的實例

    u := User{"octoboy", 101}

    獲取字段名

    首先獲取變量的Type變量

    t := reflect.TypeOf(u)

    需要注意的是,如果傳入的u是個指針,比如&User{"octoboy", 101}

    if t.Kind() == reflect.Ptr {
    	t = t.Elem()
    }

    這里通過Kind()函數獲取變量的類型,判斷如果類型為指針 需要使用Elem()獲取指針指向的內容。

    然后遍歷結構體的字段,獲取其字段名稱

    	for i := 0; i < t.NumField(); i++ {
    		fmt.Println(t.Field(i).Name)
    	}

    輸出結果:

    UserName

    UserId

    獲取字段類型和值

    v := reflect.ValueOf(u)
    if v.Kind() == reflect.Ptr { //類型為指針 需要取elem
    	v = v.Elem()
    }

    獲取字段的值或者賦值,需要用到ValueOf方法

    for i := 0; i < v.NumField(); i++ {
    	//v.Field(i).Int() v.Field(i).String() 都可以把值返回出來,相當于斷言 類型不匹配會直接panic
    	//直接斷成interface 任意類型
    	fmt.Println(v.Field(i).Interface())
    }

    輸出結果:

    zyg

    101

    繼續輸出成員變量的類型

    for i := 0; i < v.NumField(); i++ {
    	fmt.Println(v.Field(i).Kind())
    }

    輸出結果:

    string

    int

    設置字段值

    靜態賦值

    	//設置字段值
    	va := reflect.ValueOf(&u) //這里必須使用指針 否則后面調用Set無法使用無地址的值
    	if va.Kind() == reflect.Ptr { //類型為指針 需要取elem 意為取它指向的內容值
    		va = va.Elem()
    	for i := 0; i < va.NumField(); i++ {
    		//兩種方法取設置字段的值,第二種更為統一
    		if va.Field(i).Kind() == reflect.String {
    			//重要 如果需要使用set取修改u中的值,需要在ValueOf中傳入u的地址。否則會因為SetString使用了一個不能被尋址的值而造成panic
    			va.Field(i).SetString("octoboy")
    		}
    		if va.Field(i).Kind() == reflect.Int {
    			va.Field(i).Set(reflect.ValueOf(123))
    		}
    	}

    interface切片映射成結構體(動態賦值)

    	//練手
    	values := []interface{}{"octoboy", 123}
    	for i := 0; i < va.NumField(); i++ {
    		if reflect.ValueOf(values[i]).Kind() == va.Field(i).Kind() {
    			va.Field(i).Set(reflect.ValueOf(values[i]))
    		}
    	}

    打印以上兩種結構題變量

    輸出結果:

    &{octoboy 123}

    進階&mdash;map映射成結構體

    有如下代碼

    	//練習 把map映射成struct
    	set := map[string]interface{}{
    		"UserName": "zyg",
    		"UserId":   101,
    		"Age":      19,
    		"Sex":      1,
    	}
    	user := &User{}
    	MapToStruct(set, user)
    	fmt.Println(user)

    要求將map映射到user結構題中,即如果User的字段名如存在于map的key中,則將對應的value值賦給user結構題的成員變量

    有如下實現

    //str類型為interface{} 代表可以傳入任意的結構體
    func MapToStruct(m map[string]interface{}, str interface{}) {
    	val := reflect.ValueOf(str)
    	if val.Kind() != reflect.Ptr {//必須是指針 否則無法用Set賦值
    		panic(any("must be ptr!"))
    	}
    	val = val.Elem()
    	if val.Kind() != reflect.Struct { //指針指向的必須是結構體
    		panic(any("must be struct"))
    	}
    	for i := 0; i < val.NumField(); i++ {
    		name := val.Type().Field(i).Name //value轉type后取字段名稱
    		if v, ok := m[name]; ok {        //如果根據tag做映射,就使用val.Type().Field(i).Tag.Get("name")作為key
    			if reflect.ValueOf(v).Kind() == val.Field(i).Kind() {
    				val.Field(i).Set(reflect.ValueOf(v))
    			}
    		}
    	}
    }

    關于“Golang reflect反射如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    涡阳县| 乡城县| 南川市| 滦南县| 嘉荫县| 精河县| 巴塘县| 阜新市| 徐闻县| 壶关县| 成都市| 阿克苏市| 横峰县| 囊谦县| 石楼县| 开封县| 息烽县| 区。| 昌江| 赤峰市| 镇赉县| 牟定县| 革吉县| 乐山市| 通城县| 沙洋县| 仙居县| 通榆县| 达日县| 黄冈市| 罗山县| 阿拉善右旗| 阜宁县| 米易县| 蚌埠市| 榆中县| 从化市| 农安县| 东方市| 专栏| 辽中县|