//反射 練習
//獲取字段的類型信息,方法信息, 屬性信息
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())
//取出類型后,需要對類型進行校驗,
//查看是否是規(guī)定的類型
if k :=t.Kind(); k != reflect.Struct {
//如果不是規(guī)定的Struct類型的話,就需要進行
//異常處理
fmt.Println("輸入?yún)?shù)的類型不匹配!")
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)
}
}
//反射 是如何處理 匿名字段的?
package main
import (
"reflect"
"fmt"
)
type Stu struct {
Id int
Name string
Age int
}
type Man struct {
//這里你要注意一下,你創(chuàng)建的屬性,是有順序的,是有下標的
//如Stu 下標 就是0, title下標就是1
// Stu 就是匿名屬性
Stu
title string
}
func main() {
//注意,對匿名字段進行初始化時的方式,其實本質(zhì)上跟其他屬性是一樣的
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
}
//如果通過反射,對基本類型進行修改
package main
import (
"reflect"
"fmt"
)
func main() {
//下面測試,對基本類型的修改 操作
x := 456
//傳遞的參數(shù)是 地址
v := reflect.ValueOf(&x)
//Elem方法,是取出元素值來,然后通過setint方法,進行重新設置
v.Elem().SetInt(789)
fmt.Println(x)
}
//如果通過反射,對復雜類型進行修改
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")
}
}
//通過反射,進行方法的調(diào)用,相當于動態(tài)調(diào)用了
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)
}
//注意======目前沒有發(fā)現(xiàn)====如何通過====反射===來獲取=====私有方法
func (teacher Teacher)info(){
fmt.Println("=====")
}
func main() {
teacher := Teacher{Id:34, Name:"Thor",Age:34}
teacher.Show("Hawkeye")
//下面通過反射,調(diào)用show方法
v := reflect.ValueOf(teacher)
//獲取show方法
m := v.MethodByName("Show")
//校驗一下,是否獲取到show方法呢
if !m.IsValid() {
fmt.Printf("=======沒有獲取到制定的方法====")
return
}
//參數(shù)必須是切片類型
//reflect.Value{} 這里面,可以設定多個參數(shù)類型
//目前,我們這里只有一個string類型的參數(shù)
//
args := []reflect.Value{reflect.ValueOf("Hulk")}
m.Call(args)
}
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡助力業(yè)務部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統(tǒng)配攻擊溯源,準確進行流量調(diào)度,確保服務器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務器買多久送多久。
在延吉等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供成都網(wǎng)站建設、成都做網(wǎng)站 網(wǎng)站設計制作按需求定制網(wǎng)站,公司網(wǎng)站建設,企業(yè)網(wǎng)站建設,成都品牌網(wǎng)站建設,全網(wǎng)營銷推廣,外貿(mào)網(wǎng)站建設,延吉網(wǎng)站建設費用合理。
網(wǎng)站名稱:Go語言之reflection-創(chuàng)新互聯(lián)
文章分享:http://www.rwnh.cn/article24/jdhce.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計公司、定制開發(fā)、Google、小程序開發(fā)、營銷型網(wǎng)站建設、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容