GoLangStudy:day7
Go day7
golang语法解析:内置pair结构与反射机制
1.内置pair结构
示意图:

变量的type和value就是一个pair对,并且pair对在传递的过程中永远不变
示例代码:
package main
import "fmt"
func main() {
var a string
//这里的type和value都是指针
//a的pair对:pair<type:string,value:"flora">
a = "flora"
//alltype的pair对:pair<type:string,value:"flora">
var alltype interface{}
alltype = a
//对alltype进行断言
str, _ := alltype.(string)
fmt.Println(str)
}
输出结果:flora
在golang里,断言机制可以当做类型转换的工具来用
示例代码:
package main
import "fmt"
// 定义接口1
type ReadBook interface {
Readbook()
}
// 定义接口2
type WriteBook interface {
Writebook()
}
// 定义结构体
type Book struct{}
// 实现接口,使Book同时继承于readbook和writebook接口
func (b *Book) Readbook() {
fmt.Println("ReadBook test...")
}
func (b *Book) Writebook() {
fmt.Println("Writebook test...")
}
func main() {
//因为pair对是指针,所以这里取Book{}地址
//pair<type:Book,value:Book{}地址>
b := &Book{}
var r ReadBook
//pair<type:Book,value:Book{}地址>
r = b
r.Readbook()
var w WriteBook
//pair<type:Book,value:Book{}地址>
//此处断言成功原因:r和w本质上都是一种type:Book
//直接w=r会报错,所以我们需要断言机制来让w的本质显现,从而调用本质Book的方法
w = r.(WriteBook)
w.Writebook()
}
输出结果:
ReadBook test...
Writebook test...
2.reflect反射机制用法
前提条件:reflect包

简单反射示例(基础数据类型):
package main
import (
"fmt"
"reflect"
)
func ReflectNum(arg interface{}) {
fmt.Println("arg type :", reflect.TypeOf(arg))
fmt.Println("arg value :", reflect.ValueOf(arg))
}
func main() {
var a float64
a = 3.14159
ReflectNum(a)
}
输出结果:
arg type : float64
arg value : 3.14159
进阶反射示例(复杂数据类型:结构体):
package main
import (
"fmt"
"reflect"
)
type User struct {
Id int
Name string
Age int
}
func (u User) Call() {
fmt.Println("User Called.....")
}
func main() {
user := User{1, "flora", 18}
//将user传入反射函数
UserReflectTest(user)
}
func UserReflectTest(arg interface{}) {
//获取arg的类型并输出,输出格式为 包名.类名
inputType := reflect.TypeOf(arg)
fmt.Println("input arg type:", inputType)
//获取arg的值并输出
inputValue := reflect.ValueOf(arg)
fmt.Println("input arg value:", inputValue)
fmt.Println("-----------------------")
//通过type获取类内字段
//1.获取参数的reflect.Type,通过Type得到NumField(字段数),进行遍历
//2.得到每个field(数据类型)
//3.通过field的Interface()方法得到对应的value
for i := 0; i < inputType.NumField(); i++ {
field := inputType.Field(i)
value := inputValue.Field(i).Interface()
fmt.Printf("%s:%v=%v\n", field.Name, field.Type, value)
}
fmt.Println("------------------------")
//通过type获取类的方法并调用
for i := 0; i < inputType.NumMethod(); i++ {
m := inputType.Method(i)
fmt.Printf("%s: %v\n", m.Name, m.Type)
}
}
输出结果:
input arg type: main.User
input arg value: {1 flora 18}
-----------------------
Id:int=1
Name:string=flora
Age:int=18
------------------------
Call: func(main.User)
3.结构体标签Tag
package main
import (
"fmt"
"reflect"
)
type resume struct {
//我们可以在字段后面使用反引号添加标签
//标签格式为键值对形式,且值一般为string类型
Name string `info:"name" doc:"我的名字"`
Sex string `info:"sex"`
}
func findTag(str interface{}) {
t := reflect.TypeOf(str).Elem()
for i := 0; i < t.NumField(); i++ {
taginfo := t.Field(i).Tag.Get("info")
tagdoc := t.Field(i).Tag.Get("doc")
fmt.Println("info:", taginfo, "doc:", tagdoc)
}
}
func main() {
var re resume
findTag(&re)
}
输出结果:
info: name doc: 我的名字
info: sex doc:
浙公网安备 33010602011771号