Go語言之reflection

來源:互聯網
上載者:User

標籤:reflection

reflection 反射
  • 反射可大大提高程式的靈活性,使得interface{}有更大的發揮餘地
  • 反射使用TypeOf和ValueOf函數從介面中擷取目標對象資訊
  • 反射會將匿名欄位作為獨立欄位(匿名欄位本質)
  • 想要利用反射修改對象狀態,前提是interface.data是settable,即pointer-interface
  • 通過反射可以"動態"調用方法
舉例1、通過反射來擷取屬性資訊,方法資訊
//反射  練習//擷取欄位的類型資訊,方法資訊, 屬性資訊package mainimport (    "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 mainimport (    "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 mainimport (    "reflect"    "fmt")func main() {    //下面測試,對基本類型的修改 操作    x := 456    //傳遞的參數是  地址    v := reflect.ValueOf(&x)    //Elem方法,是取出元素值來,然後通過setint方法,進行重新設定    v.Elem().SetInt(789)    fmt.Println(x)}
4、通過反射 對複雜類型進行修改
//如果通過反射,對複雜類型進行修改package mainimport (    "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 mainimport (    "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)}

Go語言之reflection

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.