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.总结

posted @ 2021-10-09 10:29  可可逗豆  阅读(35)  评论(0)    收藏  举报