Go语言接口和反射
Posted parallel-y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言接口和反射相关的知识,希望对你有一定的参考价值。
一、接口
定义
接口定义了一个对象的行为规范,制定以规范并不实现,具体的对象需要实现规范的细节
//接口定义 type 接口名 interface //定义一个接口 Talk() Eat() int //返回int型 Run()
接口的实现
一个对象只要包含接口中的方法,那么就是实现了这个接口,接口类型的变量可以保存具体类型的实例
type Animal interface Talk() Eat() Name() string type Dog struct func (d Dog) Talk() fmt.Println("汪汪") func (d Dog) Eat() fmt.Println("吃骨头") func (d Dog) Name() string fmt.Println("旺财") return "旺财" func test() var b Dog var a Animal a = b a.Name() a,Eat() a.Talk()
接口调用sort排序
type Student struct Name string Id string Age int type StudentArray []Student func (p StudentArray) Len() int return len(p) func (p StudentArray) Less(i, j int) bool return p[i].Name > p[j].Name func (p StudentArray) Swap(i,j int) p[i],p[j] = p[j],p[i] func test() var stus StudentArray for i := 0;i<10;i++ stu := Student Name : fmt.Sprintf("stu%d",rand.Intn(100)), Id : fmt.Sprintf("110%d",rand.Intn()), Age : randIntn(100), stus = append(stus,stu) for _,v := range stus fmt.Println(v) fmt.Println("\n\n") sort.Sort(stus) for _,v := range stus fmt.Println(v)
空接口
空接口没有定义任何方法,所以任何类型都能实现空接口
func test() var a interface var b int = 100 a = b fmt.Printlf(%T %v\n",a,a) //int 100 var c string = "hi" a = c fmt.Printf("%T %v\n",a,a) //string hi var d map[string]int = make(map[string]int,10) d["abc"] = 100 d["aaa"] = 30 a = d fmt.Printf("%T %v\n",a,a) //map[string]int map[abc:100 aaa:30] func Descrtribe(a interface) fmt.Printf("type = %T %v\n",a,a) type Student struct Name string Sex int func test2() a := 99 describe(a) //type=int 99 b := "hello" describe(b) //type = string hello var stu Student = Student Name:"user01", Sex:1, describe(stu) //type = main.Student user01 1
类型断言
获取接口类型里面存储的具体值
//OK语句判断 func describe(a interface) s,ok := a.(int) if ok //使用ok语法,防止传入类型错误报错 fmt.Println(s) return str,ok := a.(string) if ok fmt.Println(str) return f,ok := a.(float32) if ok fmt.Println(f) return fmt.Println("输入错误") return func test() var a int = 100 describe(a) var b string = "hi" describe(b) //sitch-type语句判断 func testSwitch(a interface) switch v := a.(type) case stirng:L fmt.Printf("a is string,value:%v\n",v) case int: fmt.Printf("a is int,value:%v\n", v) case float32: fmt.Printf("a is float32,value:%v\n", v) default: fmt.Println("not support type\n") func test2() var a int = 100 testSwitch(a) var b string = "Parallel" testSAwitch(b)
指针接收和值接收区别
值类型实现的接口指针类型变量可以存入,指针类型实现的接口值类型变量不能存入
//同一兑现够可以实现多个接口 type Animal interface Talk() type Bu interface Bu() type Dog struct func (d Dog) Talk() fmt.Println("汪汪") func (d Dog) Bu() fmt.Println(*狗是哺乳动物") func test() var d Dog var a Animal a = d a.Talk() var b Bu b = d b.Bu()
接口实现链表
type LinkNode struct data interface next *LinkNode type Link struct head *LinkNode tail *LikNode func (p *Link) InsertHead(data interface) node := &LinkNode data : data, next : nil, if p.taiil == nil && p.head == nil p.tail = node p.head = node return node.next = p.head p.head = node func (p *Link) InsertTail(data interfdace) node := &LinkNode data : data, next : nil, if p.tail == nil && p.head p.tail = node p.head = node reutrn p.tail.next = node p.tail = node func (p *Link) Trans() q := p.head if q != nil fmt.Println(q.data) q = q.next func main() var intLink Link for i := 0;i<10;i++ intLink.InsertHead(i) intLink.InsertTail(i) intLink.Trans()
接口嵌套
type Animal interface Eat() type Describle interface Describled() type AdvanceAnimal interface Animal Describle type Dog struct func (d Dog) Eat() fmt.Println("狗吃屎") func (d Dog) Describled() fmt.Println("狗") func test() var d Dog var a AdvanceAnimal a = d a.Eat() a.Describled()
二、反射
定义
空接口可以存储任何类型的变量,在运行时动态的获取一个变量的类型信息和值信息就是反射
//获取类型信息:reflect.TypeOf import "fmt" "reflect" func reflect_example(a interface) t := reflect.TypeOf(a) fmt.Printf("type of a is:%v\n",t) func test() var x float32 = 3.4 reflect_example(x) //获取变量的类型:Type.Kind() import ( "fmt" "reflect" func reflect_example(a interface) t := reflect.TypeOf(a) fmt.Printf("type of a is :%v\n",t) k := t.Kind() switch k case reflect.Int64: fmt.Println("a is int64") case reflect.String: fmt.Printf("a is string") func test() var x float32 = 3.4 reflect_example(x) //获取值信息:reflect.ValueOf func reflect_value(a interface) v := reflect.ValueOf(a) k := v.Kind() switch k case reflect.Int64: fmt.Printf("a is int64,value is :%d",v.int()) case reflect.Float64: fmt.Printf("a is Float64,value is:%f",v.Float()) func test() var x float64 = 3.4 reflect_value(x) //反射设置变量值:value.Elem().SetFloat() func reflect_set_value(a interface) v := reflect.ValueOf(a) k := v.Kind() switch k case reflect.Int64: v.SetInt(100) fmt.Printf("a is int64,value is :%d",v.Int()) case reflect.Float64: v.SetFloat(6.8) fmt.Printf("a is Float64,value is:%f",v.Float()) case reflect.Ptr: fmt.Printf("set a to 6.8\n") qv.Elem().SetFloat(6.8) //Elem()相当于指针赋值中的* func test() var x float64 = 3.4 reflect_set_valur(&x) fmt.Printf("x value is %v\n",x) /* 注: var *p int = new(int) *p = 100 //正常指针赋值,设置的值需要和变量类型匹配 */
结构体反射
获取和设置结构体字段的信息
//获取结构体信息 type Student struct Name string Sex int Age int func test() var s Student v := reflect.ValueOf(s) t := v.Type() kind := t.Kind() switch kind case reflect.Int64: fmt.Printf("s is int64\n") case reflect.Float32: fmt.Println("s is Float32\n") case reflect.Struct: fmt.Printf("s is struct\n") fmt.Printf("field num of s is %d\n",v.NumField()) //获取结构体的参数个数用NumField() for i:= 0;i<v.NumField();i++ field := v.Field(i) fmt.Printf("name:%s type:%v value:%v\n",t.Field(i).Name,field.Type(),field.Interface()) default: fmt.Println("default") //设置结构体相关字段的值 type Student struct Name stirng Sex int Age int func test() var s Student v := reflect.ValueOf(&s) v.Elem().Field(0).SetString("stu01") v.Elem().FieldByName("Sex").SetInt(2) v.Elem().FieldByName("Age").SetInt(15) fmt.Printf("s:%#v\n",s)
获取和调用结构体方法中的信息
//获取结构体的方法信息 type Student struct Name string Sex int Age int Score float32 func (s *Student) SetName(name string) s.Name = name func (s *Student) Print() fmt.printf("%#v\n",s) func test() var s Student s.SetName("xxx") v := reflect.ValueOf(&s) t := v.Type() fmt.Printf("struct student have %d methods\n",t.NumMethod()) for i := 0;i<NumMethod();i++ method := t.Method(i) fmt.Printf("struct %d method,name:%s type :%v\n",i,method.Name,method.Type) //调用结构体中的方法 type Student struct Name string Sex int Age int Score float 32 func (s *Student) SetName(name string) s.Name = name func (s *Student) Print() fmt.Printf("%#v\n",s) func test2() var s Student s.SetName("xxx") v := reflect.ValueOf(&s) m1 := v.MethodByName("Print") var args []reflect.Value m1.Call(args) //调用有参数结构体的方法 m2 := v.MethodByName("SetName") var args2 []reflect.Value name := "stu01" nameVal := reflect.ValueOf(name) args2 = append(args2,nameVal) m2.Call(args2) m1.Call(args)
以上是关于Go语言接口和反射的主要内容,如果未能解决你的问题,请参考以下文章