Go語言中的反射機制reflect

來源:互聯網
上載者:User

標籤:Go語言中的反射機制reflect   Go語言反射機制   Go語言reflect   

go的反射機制是要通過介面來進行的,而類似於Java的Object的空介面可以和任何類型進行互動,因此對基礎資料型別 (Elementary Data Type)等的反射也直接利用了這一特點。

package mainimport (    "fmt"    "reflect")type Student struct {    Name    string    Age     int    Sex     uint // 0-女性,1-男性    Address string}func (stu Student) Print() {    sex := "女"    if stu.Sex == 1 {        sex = "男"    }    fmt.Printf("姓名:%s,年齡:%d,性別:%s,地址:%s", stu.Name, stu.Age, sex, stu.Address)}func (stu Student) Say(content string) string{    return fmt.Sprintf("%s說:%s", stu.Name, content)}func main() {    // ============================================================操作基礎資料型別 (Elementary Data Type)    var a1 int = 1    var a2 string = "中國"    var a3 = [...]byte{1, 2, 3}       // 數組    var a4 = []int{5, 6, 7}           // 切片    var a5 = map[string]int{"china":1, "usa":2} // Map    // 轉化成reflect對象,reflect.Type和reflect.Value    // TypeOf()返回的資料類型是*reflect.rtype,ValueOf()返回的資料類型是reflect.Value    t1 := reflect.TypeOf(a1);   v1 := reflect.ValueOf(a1)    t2 := reflect.TypeOf(a2);   v2 := reflect.ValueOf(a2)    t3 := reflect.TypeOf(a3);   v3 := reflect.ValueOf(a3)    t4 := reflect.TypeOf(a3);   v4 := reflect.ValueOf(a4)    t5 := reflect.TypeOf(a3);   v5 := reflect.ValueOf(a5)    fmt.Println("a1====", t1, v1)    fmt.Println("a2====", t2, v2)    fmt.Println("a3====", t3, v3)    fmt.Println("a4====", t4, v4)    fmt.Println("a5====", t5, v5)    fmt.Println()    // 取值    fmt.Println("a1的值:", v1.Int())    fmt.Println("a2的值:", v2.String())    fmt.Println("a3中下標為1的元素的值:", v3.Index(1))    fmt.Println("a4中下標為1的元素的值:", v4.Index(1))    fmt.Println("a4中取[1,3)的子切片:", v4.Slice(1, 3))    fmt.Println("a5中所有key:", v5.MapKeys())    fmt.Print("遍曆a5中的value:")    for _, key := range v5.MapKeys() {        fmt.Print(key, "====", v5.MapIndex(key), "\t")    }    fmt.Println()    fmt.Println()    // 擷取類型    fmt.Println("a1的類型:", v1.Type())    fmt.Println("a2的類型:", v2.Type())    fmt.Println("a3的類型:", v3.Type())    fmt.Println("a4的類型:", v4.Type())    fmt.Println("a5的類型:", v5.Type())    fmt.Println()    // Kind類型判斷,Kind()    fmt.Println("a1的類型是否為int:", v1.Kind() == reflect.Int)    fmt.Println("a2的類型是否為string:", v2.Kind() == reflect.String)    fmt.Println("a3的類型是否為array:", v3.Kind() == reflect.Array)    fmt.Println("a4的類型是否為slice:", v4.Kind() == reflect.Slice)    fmt.Println("a5的類型是否為map:", v5.Kind() == reflect.Map)    fmt.Println()    // 介面類型變數,Interface是擷取該value的值,返回的是一個interface對象    fmt.Printf("a1====%T\t%v\n", v1.Interface(),  v1.Interface())    fmt.Printf("a2====%T\t%v\n", v2.Interface(),  v2.Interface())    fmt.Printf("a3====%T\t%v\n", v3.Interface(),  v3.Interface())    fmt.Printf("a4====%T\t%v\n", v4.Interface(),  v4.Interface())    fmt.Printf("a5====%T\t%v\n", v5.Interface(),  v5.Interface())    fmt.Println()    // 判斷是否可以修改    fmt.Println("a1通過反射是否可以進行修改:", v1.CanSet())    fmt.Println("a2通過反射是否可以進行修改:", v2.CanSet())    fmt.Println("a3通過反射是否可以進行修改:", v3.CanSet())    fmt.Println("a4通過反射是否可以進行修改:", v4.CanSet())    fmt.Println("a5通過反射是否可以進行修改:", v5.CanSet())    fmt.Println()    // 修改,必須傳指標,且調用Elem()    vv1 := reflect.ValueOf(&a1).Elem()    fmt.Printf("vv1的類型:%T,a1現在是否可以通過:%v\n", vv1, vv1.CanSet())    vv2 := reflect.ValueOf(&a2).Elem()    vv3 := reflect.ValueOf(&a3).Elem()    vv4 := reflect.ValueOf(&a4).Elem()    vv5 := reflect.ValueOf(&a5).Elem()    vv1.SetInt(100) // 修改    vv2.SetString("美國")    var temp byte = 90    vv3.Index(0).Set(reflect.ValueOf(temp)) // 必須傳reflect.Value類型    vv4.Index(0).SetInt(900)    // 必須傳reflect.Value類型    vv5.SetMapIndex(reflect.ValueOf("china"), reflect.ValueOf(111))    fmt.Println("a1修改後的值:", a1)    fmt.Println("a2修改後的值:", a2)    fmt.Println("a3修改後的值:", a3)    fmt.Println("a4修改後的值:", a4)    fmt.Println("a5修改後的值:", a5)    // ============================================================操作結構體    stu := Student{"李四", 18, 1, "中國北京市天安門10000號"}    // 轉化成reflect對象,reflect.Type和reflect.Value    st1 := reflect.TypeOf(stu)    sv1 := reflect.ValueOf(stu)    fmt.Println(st1, "====", sv1)    // 擷取結構體名稱    fmt.Println(st1.Name())    // 判斷Kind類型    fmt.Println(st1.Kind() == reflect.Struct)    // 擷取結構體中欄位數量    fmt.Println(st1.NumField())    // 擷取結構體中每個欄位的值    for i := 0 ; i < st1.NumField() ; i++ {        fieldName := st1.Field(i).Name        // 取欄位名        fieldType := st1.Field(i).Type        fieldVal := sv1.Field(i).Interface()  // 取值        fmt.Printf("欄位名:%v,類型:%v,值:%v\n", fieldName, fieldType, fieldVal)    }    // 擷取結構體的方法數量    fmt.Println(st1.NumMethod())    // 遍曆所有方法的名稱和類型    for i := 0 ; i < st1.NumMethod() ; i++ {        method := st1.Method(i)        fmt.Println(method.Name, "====", method.Type)    }    // 通過反射執行方法    m1 := sv1.MethodByName("Print")    m1.Call(nil)// 不帶參數和傳回值    fmt.Println()    m2 := sv1.MethodByName("Say")    params := []reflect.Value{reflect.ValueOf("你好啊!")}    res := m2.Call(params) // 帶參數和傳回值,參數是reflect.Value的切片,傳回值也一樣    fmt.Println(res[0].String())}

Go語言中的反射機制reflect

相關文章

聯繫我們

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