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

溫馨提示×

溫馨提示×

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

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

Go語言之reflection

發布時間:2020-07-29 06:47:07 來源:網絡 閱讀:700 作者:故新 欄目:編程語言

reflection 反射

  • 反射可大大提高程序的靈活性,使得interface{}有更大的發揮余地
  • 反射使用TypeOf和ValueOf函數從接口中獲取目標對象信息
  • 反射會將匿名字段作為獨立字段(匿名字段本質)
  • 想要利用反射修改對象狀態,前提是interface.data是settable,即pointer-interface
  • 通過反射可以"動態"調用方法

舉例

1、通過反射來獲取屬性信息,方法信息

//反射  練習
//獲取字段的類型信息,方法信息, 屬性信息
package main

import (
    "fmt"
    "reflect"
)

type User struct {
    Id int
    Name string
    Age int
}

func (user User) Hello(){
    fmt.Println("hello world")
}

func main() {
    user := User{Id:2, Name:"xiaoqiang",Age:30}
    info(user)
}

//定義一個方法
//此方法接收的是一個空接口
//這樣的話,其實是任何類型都可以接收了
func info(o interface{}) {
    //獲取o的類型
    t := reflect.TypeOf(o)

    fmt.Println("Type:\t", t.Name())

    //取出類型后,需要對類型進行校驗,
    //查看是否是規定的類型
    if k :=t.Kind(); k != reflect.Struct {
        //如果不是規定的Struct類型的話,就需要進行
        //異常處理
        fmt.Println("輸入參數的類型不匹配!")
        return
    }

    //獲取o的屬性
    v := reflect.ValueOf(o)
    fmt.Println("Fields:\n")

    //開始遍歷,輸出字段
    for i := 0; i < t.NumField(); i++ {
        //獲取屬性下標
        f := t.Field(i)
        val := v.Field(i).Interface()
        //輸出屬性的名稱,類型,對應的值
        fmt.Printf("%6s:%v = %v\n", f.Name, f.Type, val)
    }

    //開始獲取 方法的基本信息
    for i:=0; i<t.NumMethod(); i++ {
        m := t.Method(i)
        fmt.Printf("%6s:%v\n", m.Name, m.Type)
    }

}

2、反射是如何 獲取 匿名字段呢?

//反射 是如何處理 匿名字段的?
package main

import (
    "reflect"
    "fmt"
)

type Stu struct {
    Id int
    Name string
    Age int
}

type Man struct {
    //這里你要注意一下,你創建的屬性,是有順序的,是有下標的
    //如Stu 下標 就是0, title下標就是1
    // Stu 就是匿名屬性
    Stu
    title string
}

func main() {
    //注意,對匿名字段進行初始化時的方式,其實本質上跟其他屬性是一樣的
    m := Man{Stu:Stu{Id:2,Name:"Jack",Age:19}, title:"Manager"}
    t := reflect.TypeOf(m)

    //取匿名字段的方式
    //FieldByIndex 方法,傳入的是一個切片slice類型
    //第1個0,表示,匿名字段在Man中的下標位置
    //第2個0,表示,你要取匿名字段中哪個屬性的下標
    fmt.Printf("%#v\n", t.FieldByIndex([]int{0,0})) //取的是id
    fmt.Printf("%#v\n", t.FieldByIndex([]int{0,1})) //取的是Name
    fmt.Printf("%#v\n", t.FieldByIndex([]int{0,2})) //取的是Age

}

3、通過反射對基本類型進行修改


//如果通過反射,對基本類型進行修改
package main

import (
    "reflect"
    "fmt"
)

func main() {
    //下面測試,對基本類型的修改 操作
    x := 456
    //傳遞的參數是  地址
    v := reflect.ValueOf(&x)

    //Elem方法,是取出元素值來,然后通過setint方法,進行重新設置
    v.Elem().SetInt(789)

    fmt.Println(x)
}

4、通過反射 對復雜類型進行修改

//如果通過反射,對復雜類型進行修改
package main

import (
    "reflect"
    "fmt"
)

type Teac struct {
    Id int
    Name string
    Age int
}

func main() {
    teac := Teac{Id:5,Name:"Ant-man",Age:23}
    fmt.Println("teac:\t", teac)
    //傳遞的是 地址哦
    Set(&teac)
    fmt.Println("teac:\t", teac)
}

func Set(o interface{}) {
    v := reflect.ValueOf(o)
    if v.Kind() == reflect.Ptr && !v.Elem().CanSet() {
        fmt.Printf("xxx")
        return
    }else{
        v = v.Elem()
    }

    // 通過FieldByName 這個方法,直接輸入 名稱,來獲取
    f := v.FieldByName("Name")

    //校驗,是否取到Name屬性的值
    if !f.IsValid() {
        fmt.Printf("BAD")
        return
    }

    //然后,再校驗,類型是否匹配
    if f.Kind() == reflect.String {
        f.SetString("Iron Man")
    }

}

5、通過反射對方法進行動態調用

//通過反射,進行方法的調用,相當于動態調用了
package main

import (
    "fmt"
    "reflect"
)

type Teacher struct {
    Id int
    Name string
    Age int
}

//通過receiver將Show方法,跟Teacher類型,進行綁定
func (teacher Teacher)Show(name string) {
    fmt.Println("hello, ", name, ", my name is ", teacher.Name)
}

//注意======目前沒有發現====如何通過====反射===來獲取=====私有方法
func (teacher Teacher)info(){
    fmt.Println("=====")
}

func main() {
    teacher := Teacher{Id:34, Name:"Thor",Age:34}
    teacher.Show("Hawkeye")

    //下面通過反射,調用show方法
    v := reflect.ValueOf(teacher)
    //獲取show方法
    m := v.MethodByName("Show")

    //校驗一下,是否獲取到show方法呢
    if !m.IsValid() {
        fmt.Printf("=======沒有獲取到制定的方法====")
        return
    }

    //參數必須是切片類型
    //reflect.Value{}   這里面,可以設定多個參數類型
    //目前,我們這里只有一個string類型的參數
    //
    args := []reflect.Value{reflect.ValueOf("Hulk")}
    m.Call(args)
}
向AI問一下細節

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

AI

长治县| 新化县| 陵川县| 永平县| 邳州市| 江阴市| 吉隆县| 陆丰市| 温州市| 峨边| 六枝特区| 仪征市| 美姑县| 都安| 邵武市| 凌海市| 安宁市| 庆元县| 江门市| 普定县| 星座| 嵊州市| 仁怀市| 雅江县| 漾濞| 崇礼县| 南通市| 寿光市| 库尔勒市| 观塘区| 永平县| 红河县| 彝良县| 全南县| 苏尼特右旗| 汉中市| 道孚县| 赣榆县| 威信县| 张家港市| 合阳县|