16.反射
1.变量内置pair构造

示例代码
pairs.go
package chapter13
import "fmt"
func RunPair() {
var a string
// pair<statictype:string, value:"aceld">
a = "aceld"
// pair<type:string, value:"aceld">
var allType interface{}
allType = a
str, _ := allType.(string)
fmt.Println(str)
}
// 执行结果
=== RUN TestRunPair
aceld
--- PASS: TestRunPair (0.00s)
PASS
ok
pairs2.go
package chapter13
import (
"fmt"
"io"
"os"
)
func RunPair2() {
// tty: pair<type:*os.File, value:"/dev/tty"文件描述符>
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
fmt.Println("open file error", err)
return
}
// r: pair<type:, value: >
var r io.Reader
// r: pair<type:*os.File, value:"/dev/tty">
r = tty
// w: pari<type, value>
var w io.Writer
// w: pari<type:*os.File,value:"/dev/tty">
w = r.(io.Writer)
w.Write([]byte("Hello This is a test !!!\n"))
}
// 执行结果
=== RUN TestRunPair2
Hello This is a test !!!
--- PASS: TestRunPair2 (0.00s)
PASS
ok
pair3.go
package chapter13
import "fmt"
type Reader interface {
ReadBook()
}
type Writer interface {
WriteBook()
}
type Book struct{}
func (book *Book) ReadBook() {
fmt.Println("Read a book")
}
func (book *Book) WriteBook() {
fmt.Println("Write a book")
}
func RunPair3() {
// b: pair<type:Book, value:book{}地址>
b := &Book{}
// r: pair<type: ,value: >
var r Reader
// r: pair<type:Book, value:book{}地址>
r = b
r.ReadBook()
// w: pair<type: ,value: >
var w Writer
// w: pair<type:Book, value:book{}地址>
w = b
w.WriteBook() //此处的断言为什么会成功?因为 w, r 具体的type是一致的
}
// 执行结果
=== RUN TestRunPair3
Read a book
Write a book
--- PASS: TestRunPair3 (0.00s)
PASS
ok
2.反射

示例代码
reflect1.go
package chapter13
import (
"fmt"
"reflect"
)
func reflectNum(arg interface{}) {
fmt.Println("type : ", reflect.TypeOf(arg))
fmt.Println("value : ", reflect.ValueOf(arg))
}
func RunReflect1() {
var num float64 = 1.2345
reflectNum(num)
}
// 执行代码
=== RUN TestRunReflect1
type : float64
value : 1.2345
--- PASS: TestRunReflect1 (0.00s)
PASS
ok
reflect2.go
package chapter13
import (
"fmt"
"reflect"
)
type User struct {
Id int
Name string
Age int
}
// 注意这个方式 ,形参,副本
func (user User) Call() {
fmt.Println("user is called...")
fmt.Printf("%v\n", user)
}
func RunReflect2() {
user := User{1, "Jack", 18}
DoFieldAndMethod(user)
}
func DoFieldAndMethod(input interface{}) {
//获取input的type
inputType := reflect.TypeOf(input)
fmt.Println("inputType is : ", inputType.Name())
// 获取input的value
inputValue := reflect.ValueOf(input)
fmt.Println("input value is : ", inputValue)
// 通过 type 获取结构体的属性字段
// 1. 获取 interface的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("----method----reflect-----")
// 通过 type 获取结构体的属性值
for i := 0; i < inputType.NumMethod(); i++ {
method := inputType.Method(i)
fmt.Printf("%s: %v\n", method.Name, method.Type)
}
}
// 执行结果
=== RUN TestRunReflect2
inputType is : User
input value is : {1 Jack 18}
Id: int = 1
Name: string = Jack
Age: int = 18
----method----reflect-----
Call: func(chapter13.User)
--- PASS: TestRunReflect2 (0.00s)
PASS
ok
3.结构体标签
示例代码
tag1.go
package chapter13
import (
"fmt"
"reflect"
)
type resume struct {
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++ {
tagString := t.Field(i).Tag.Get("info")
tagDoc := t.Field(i).Tag.Get("doc")
fmt.Println("info: ", tagString, ", doc: ", tagDoc)
}
}
func RunTag() {
var re resume
findTag(&re)
}
// 执行结果
=== RUN TestRunTag
info: name , doc: 我的名字
info: sex , doc:
--- PASS: TestRunTag (0.00s)
PASS
ok
tag_json.go
package chapter13
import (
"encoding/json"
"fmt"
)
type Movie struct {
Title string `json:"title"`
Year int `json:"year"`
Price int `json:"rmb"`
Actors []string `json:"actors"`
}
func RunTag2() {
movie := Movie{
Title: "喜剧之王",
Year: 2000,
Price: 10,
Actors: []string{"xingye", "zhangbozhi"},
}
// 编码的过程 结构体--->>> json
jsonStr, err := json.Marshal(movie)
if err != nil {
fmt.Println("json marshal error ", err)
}
fmt.Printf("%s\n", jsonStr) //{"title":"喜剧之王","year":2000,"rmb":10,"actors":["xingye","zhangbozhi"]}
m := Movie{}
err = json.Unmarshal(jsonStr, &m)
if err != nil {
fmt.Println("json unmalshal error ", err)
}
fmt.Printf("%v\n", m)
}
// 执行结果
=== RUN TestRunTag2
{"title":"喜剧之王","year":2000,"rmb":10,"actors":["xingye","zhangbozhi"]}
{喜剧之王 2000 10 [xingye zhangbozhi]}
--- PASS: TestRunTag2 (0.00s)
PASS
ok
4.总结


浙公网安备 33010602011771号