go 速學 - 14 - 反射

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

目錄

    • 反射 reflection
      • 使用反射
        • 前提
        • 定義一個結構及方法
        • 反射所有欄位及方法
      • 訪問結構中的匿名欄位
      • 動態修改屬性的值
      • 動態調用方法

摘要

使用反射,匿名欄位,動態修改屬性,動態調用方法

反射 reflection

使用反射

前提

使用反射之前必須引用包 reflect

定義一個結構及方法

import "reflect"type User struct {    Id   int    Name string    Age  int}func (u User) say() {    fmt.Println("hello")}u := User{Id: 1, Name: "Peter", Age: 20}

反射所有欄位及方法

  • reflect.TypeOf(o) 用於獲得類型原型
  • reflect.ValueOf(o) 用於獲得值

注意要想訪問欄位的值則欄位應為 public,要想調用方法則方法應為 public

func info(o interface{}) {    //獲得參數類型的原型    t := reflect.TypeOf(o)    fmt.Println("t", t)                       //t main.User    fmt.Println("t.Name()", t.Name())         //t.Name() User    fmt.Println("t.NumField()", t.NumField()) //t.NumField() 3    v := reflect.ValueOf(o)    fmt.Println("v", v) //v <main.User Value>    //檢測類型    if k := t.Kind(); k != reflect.Struct {        return    }    //輸出屬性    for i := 0; i < t.NumField(); i++ {        f := t.Field(i)        //此時的 Field 必須為public        val := v.Field(i).Interface()        fmt.Println(f.Name, f.Type, val)        //--> outputs        //Id int 1        //Name string Peter        //Age int 20    }    fmt.Println()    //輸出方法    for i := 0; i < t.NumMethod(); i++ {        m := t.Method(i)        fmt.Println(m.Name, m.Type)        //-->outputs        //say func(main.User)    }}info(u)

訪問結構中的匿名欄位

type Manager struct {    User    title string}//typem := Manager{title: "Manager", User: User{Id: 2, Name: "Jane", Age: 22}}t := reflect.TypeOf(m)f := t.FieldByIndex([]int{0, 1})fmt.Println("f", f.Name, f.Type) //f Name string//valuev := reflect.ValueOf(m)val := v.FieldByIndex([]int{0, 1}).Interface()fmt.Println("val", val) //val Jane

使用 reflect.FieldByIndex() 方法,該方法的參數為 slice,以上第一個位置的 “0” 表示 Manager 的0號屬性(User),1表示 User 的1號屬性(Name)

動態修改屬性的值

func set(o interface{}) {    v := reflect.ValueOf(o)    ////判斷是否為指標類型且可寫    if k := v.Kind(); k != reflect.Ptr || !v.Elem().CanSet() {        fmt.Println("invalid type")        return    }    v = v.Elem()    f := v.FieldByName("Name")    //判斷指定屬性是否存在    if !f.IsValid() {        fmt.Println("invalid name")        return    }    if f.Kind() == reflect.String {        f.SetString("a")    }}u := User{Id: 1, Name: "Peter", Age: 20}fmt.Println("u.Name", u.Name) //u.Name Peterset(&u)fmt.Println("u.Name", u.Name) //u.Name aset(u)

注意以上是通過傳入指標來實現動態修改的

動態調用方法

注意調用方法時該方法應為 public

func (u User) Hello(name string) {    fmt.Println("hello ", name, " my name is ", u.Name)}u := User{Id: 1, Name: "Peter", Age: 20}v = reflect.ValueOf(u)mn := v.MethodByName("Hello")args := []reflect.Value{reflect.ValueOf("Andy")}mn.Call(args)fmt.Println("u.Name", u.Name) //hello  Andy  my name is  a
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.