Types in Go

Go 中变量拥有确定的静态类型:

  1. type Int int
  2. var i int
  3. var j Int

那么,变量 i、j 分别拥有静态类型 int、Int,且由于静态类型不一致,不能互相直接赋值。
当变量类型为接口时:

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. type person interface {
  7. Name() string
  8. }
  9. type String string
  10. func (s String) Name() string {
  11. return string(s)
  12. }
  13. func main() {
  14. var p person = String("John")
  15. fmt.Println(reflect.TypeOf(p), reflect.ValueOf(p), p.Name())
  16. }
  17. // main.String John John

Value

Kind 常量

  1. const (
  2. Invalid Kind = iota
  3. Bool
  4. Int
  5. Int8
  6. Int16
  7. Int32
  8. Int64
  9. Uint
  10. Uint8
  11. Uint16
  12. Uint32
  13. Uint64
  14. Uintptr
  15. Float32
  16. Float64
  17. Complex64
  18. Complex128
  19. Array
  20. Chan
  21. Func
  22. Interface
  23. Map
  24. Ptr
  25. Slice
  26. String
  27. Struct
  28. UnsafePointer
  29. )

内置类型

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func printValue(args ...interface{}) {
  7. for _, v := range args {
  8. doPrint(v)
  9. }
  10. }
  11. func doPrint(arg interface{}) {
  12. switch v := reflect.ValueOf(arg); v.Kind() {
  13. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  14. fmt.Printf("Int value %d\n", v.Int())
  15. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  16. fmt.Printf("UInt value %d\n", v.Uint())
  17. case reflect.Bool:
  18. fmt.Printf("Bool value %v\n", v.Bool())
  19. case reflect.Float32, reflect.Float64:
  20. fmt.Printf("Float value %f\n", v.Float())
  21. case reflect.String:
  22. fmt.Printf("String value %s\n", v.String())
  23. case reflect.Slice:
  24. fmt.Printf("Slice value %v\n", v)
  25. default:
  26. fmt.Printf("Unhandled kind %s\n", v.Kind())
  27. }
  28. }
  29. func main() {
  30. printValue(1, uint8(1), 1.0, true, "hello", []int{1, 2, 3})
  31. }

设置简单值

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func main() {
  7. i := 1
  8. v := reflect.ValueOf(i)
  9. fmt.Println("v.CanSet()", v.CanSet())
  10. pv := reflect.ValueOf(&i)
  11. fmt.Println("pv.CanSet()", pv.CanSet())
  12. pve := pv.Elem()
  13. fmt.Println("pve.CanSet()", pve.CanSet())
  14. pve.SetInt(2)
  15. fmt.Println(i)
  16. }
  17. // v.CanSet() false
  18. // pv.CanSet() false
  19. // pve.CanSet() true
  20. // 2

Struct

获取 Field、Method 等基本信息

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. type Book struct {
  7. Name string
  8. Price float32
  9. visible bool
  10. }
  11. func (b Book) Description() string {
  12. return fmt.Sprintf("Book %s, Price: %2.2f", b.Name, b.Price)
  13. }
  14. func main() {
  15. book := Book{"Redis in Action", 32.0, false}
  16. v := reflect.ValueOf(book)
  17. fmt.Println(v.Type(), v.Kind())
  18. fields := v.NumField()
  19. for i := 0; i < fields; i++ {
  20. fv := v.Field(i)
  21. fmt.Printf("Field(%d) type %s, CanSet %v\n", i, fv.Type(), fv.CanSet())
  22. }
  23. fmt.Println(v.FieldByName("Price"))
  24. methods := v.NumMethod()
  25. for i := 0; i < methods; i++ {
  26. m := v.Method(i)
  27. fmt.Println(m.Type())
  28. }
  29. fmt.Println(book.Description())
  30. }
  31. // main.Book struct
  32. // Field(0) type string, CanSet false
  33. // Field(1) type float32, CanSet false
  34. // Field(2) type bool, CanSet false
  35. // 32
  36. // func() string
  37. // Book Redis in Action, Price: 32.00

修改结构体:

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. type Book struct {
  7. Name string
  8. Price float32
  9. visible bool
  10. }
  11. func (b Book) Description() string {
  12. return fmt.Sprintf("Book %s, Price: %2.2f", b.Name, b.Price)
  13. }
  14. func main() {
  15. book := &Book{"Redis in Action", 32.0, false}
  16. v := reflect.ValueOf(book).Elem()
  17. fmt.Println(v.Type(), v.Kind())
  18. fields := v.NumField()
  19. for i := 0; i < fields; i++ {
  20. fv := v.Field(i)
  21. fmt.Printf("Field(%d) type %s, CanSet %v\n", i, fv.Type(), fv.CanSet())
  22. }
  23. v.FieldByName("Price").SetFloat(36.0)
  24. fmt.Println(book.Description())
  25. }
  26. // main.Book struct
  27. // Field(0) type string, CanSet true
  28. // Field(1) type float32, CanSet true
  29. // Field(2) type bool, CanSet false
  30. // Book Redis in Action, Price: 36.00

Slice

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func main() {
  7. s := []int{10, 20}
  8. t := reflect.TypeOf(s)
  9. v := reflect.ValueOf(s)
  10. fmt.Printf("Slice Type(%s), Kind(%s), Len(%d), Cap(%d), CanSet(%v)\n", t, v.Kind(), v.Len(), v.Cap(), v.CanSet())
  11. for i := 0; i < v.Len(); i++ {
  12. f := v.Index(i)
  13. fmt.Printf("Field(%d), Value(%d), CanSet(%v)\n", i, f.Int(), f.CanSet())
  14. f.SetInt(f.Int() + 1)
  15. }
  16. fmt.Println(s)
  17. }
  18. // Slice Type([]int), Kind(slice), Len(2), Cap(2), CanSet(false)
  19. // Field(0), Value(10), CanSet(true)
  20. // Field(1), Value(20), CanSet(true)
  21. // [11 21]

Append 操作

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func main() {
  7. s := []int{1, 2}
  8. v := reflect.ValueOf(&s).Elem()
  9. fmt.Printf("Slice Type(%s), Kind(%s), Len(%d), Cap(%d), CanSet(%v)\n", v.Type(), v.Kind(), v.Len(), v.Cap(), v.CanSet())
  10. v.Set(reflect.Append(v, reflect.ValueOf(3), reflect.ValueOf(4), reflect.ValueOf(5)))
  11. fmt.Printf("Slice Type(%s), Kind(%s), Len(%d), Cap(%d), CanSet(%v)\n", v.Type(), v.Kind(), v.Len(), v.Cap(), v.CanSet())
  12. fmt.Println(s)
  13. }
  14. // Slice Type([]int), Kind(slice), Len(2), Cap(2), CanSet(true)
  15. // Slice Type([]int), Kind(slice), Len(5), Cap(8), CanSet(true)
  16. // [1 2 3 4 5]

Map

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func keys(v reflect.Value) []reflect.Value {
  7. return v.MapKeys()
  8. }
  9. func main() {
  10. s := map[string]int64{
  11. "A": 100,
  12. "B": 80,
  13. }
  14. v := reflect.ValueOf(&s).Elem()
  15. fmt.Printf("Map Type(%s), Kind(%s), Key(%s), Len(%d), CanSet(%v)\n", v.Type(), v.Kind(), v.Type().Key(), v.Len(), v.CanSet())
  16. for _, k := range keys(v) {
  17. fmt.Printf("Key(%s), Value(%d), CanSet(%v)\n", k, v.MapIndex(k).Int(), v.MapIndex(k).CanSet())
  18. v.SetMapIndex(k, reflect.ValueOf(v.MapIndex(k).Int() * 2))
  19. }
  20. v.SetMapIndex(reflect.ValueOf("C"), reflect.ValueOf(int64(60)))
  21. fmt.Println(s)
  22. }
  23. // Map Type(map[string]int64), Kind(map), Key(string), Len(2), CanSet(true)
  24. // Key(A), Value(100), CanSet(false)
  25. // Key(B), Value(80), CanSet(false)
  26. // map[A:200 B:160 C:60]

Function

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func incr(v int) (int, error) {
  7. return v + 1, nil
  8. }
  9. func main() {
  10. t := reflect.TypeOf(incr)
  11. fmt.Printf("Function type [%v], in:[%d], out(%d), Name(%s)\n", t, t.NumIn(), t.NumOut(), t.Name())
  12. for i := 0; i < t.NumIn(); i++ {
  13. fmt.Printf("args[%d], Name(%s), Kind(%s)\n", i, t.In(i).Name(), t.In(i).Kind())
  14. }
  15. for i := 0; i < t.NumOut(); i++ {
  16. fmt.Printf("returns[%d], Name(%s), Kind(%s)\n", i, t.Out(i).Name(), t.Out(i).Kind())
  17. }
  18. fmt.Println("Comparable:", t.Comparable())
  19. }
  20. // Function type [func(int) (int, error)], in:[1], out(2), Name()
  21. // args[0], Name(int), Kind(int)
  22. // returns[0], Name(int), Kind(int)
  23. // returns[1], Name(error), Kind(interface)
  24. // Comparable: false

反射中调用函数

  1. package main
  2. import (
  3. "reflect"
  4. "fmt"
  5. )
  6. func incr(v int) (int, error) {
  7. return v + 1, nil
  8. }
  9. func main() {
  10. t := reflect.TypeOf(incr)
  11. v := reflect.ValueOf(incr)
  12. outs := v.Call([]reflect.Value{reflect.ValueOf(1)})
  13. ev := outs[t.NumOut() - 1]
  14. if t.Out(t.NumOut() - 1).Name() == "error" && ev.IsNil() {
  15. fmt.Println(outs[0])
  16. } else {
  17. fmt.Println(ev)
  18. }
  19. }
  20. // 2

Channel

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. "time"
  6. )
  7. func read(v reflect.Value) reflect.SelectCase {
  8. return reflect.SelectCase{
  9. Dir: reflect. SelectRecv,
  10. Chan: v,
  11. }
  12. }
  13. func write(ch, v reflect.Value) {
  14. ch.Send(v)
  15. }
  16. func main() {
  17. ch := make(chan int, 4)
  18. stop := make(chan struct{})
  19. go func() {
  20. sels := []reflect.SelectCase{}
  21. sels = append(sels, read(reflect.ValueOf(ch)))
  22. sels = append(sels, read(reflect.ValueOf(stop)))
  23. for {
  24. c, rv, ok := reflect.Select(sels)
  25. if !ok {
  26. break
  27. }
  28. if c == 1 { // stop channel received
  29. break
  30. }
  31. fmt.Printf("Received from Index(%d) with Value(%v)\n", c, rv)
  32. }
  33. }()
  34. write(reflect.ValueOf(ch), reflect.ValueOf(1))
  35. write(reflect.ValueOf(ch), reflect.ValueOf(2))
  36. write(reflect.ValueOf(ch), reflect.ValueOf(3))
  37. write(reflect.ValueOf(ch), reflect.ValueOf(4))
  38. time.Sleep(1 * time.Second)
  39. close(stop)
  40. }
  41. // Received from Index(0) with Value(1)
  42. // Received from Index(0) with Value(2)
  43. // Received from Index(0) with Value(3)
  44. // Received from Index(0) with Value(4)

参考资料