|
|
51CTO旗下网站
|
|
移动端

9.2.3 反射结构

《Go语言编程入门与实战技巧》第9章接口与反射,本章需要注意设计类型时确认类型的本质是原始的还是非原始的。接口是声明了一组行为并支持多态的类型,嵌入类型提供了扩展类型的能力,而无须使用继承。本节为大家介绍反射结构。

作者:黄靖钧来源:电子工业出版社|2018-09-23 09:33

9.2.3  反射结构

有些时候需要反射一个结构类型:NumField()方法返回结构内的字段数量;通过一个for循环用索引取得每个字段的值Field(i)。

我们同样能够调用已经定义的函数在结构上的方法,例如,使用索引n来调用Method(n).Call(nil):

  1. // 示例代码9-8  
  2. package main  
  3.  
  4. import (  
  5.     "fmt"  
  6.     "reflect"  
  7. )  
  8.  
  9. type NotknownType struct {  
  10.     s1, s2, s3 string  
  11. }  
  12.  
  13. func (n NotknownType) String() string {  
  14.     return n.s1 + " - " + n.s2 + " - " + n.s3  
  15. }  
  16.  
  17. var secret interface{} = NotknownType{"Google", "Go", "Code"}  
  18.  
  19. func main() {  
  20.     value :reflect.ValueOf(secret) // <main.NotknownType Value> 
  21.     typ :reflect.TypeOf(secret)    // main.NotknownType  
  22.     // 也可以这样写:  
  23.     // typ :value.Type()  // main.NotknownType  
  24.     fmt.Println(typ)  
  25.     knd :value.Kind() // struct  
  26.     fmt.Println(knd)  
  27.  
  28.     // 迭代结构的字段:  
  29.     for i :0; i < value.NumField(); i++ {  
  30.         fmt.Printf("Field %d: %v\n", i, value.Field(i))  
  31.         // 返回错误:  
  32.         // Panic: reflect.Value.SetString using value obtained using unexported field  
  33.         // value.Field(i).SetString("C#")  
  34.     }  
  35.  
  36.     // 调用第一个方法,即string():  
  37.     results :value.Method(0).Call(nil)  
  38.     fmt.Println(results) // [Google - Go - Code]  
  39. }  
  40. /*  
  41. 返回:  
  42. main.NotknownType  
  43. struct  
  44. Field 0: Google  
  45. Field 1: Go  
  46. Field 2: Code  
  47. [Google - Go - Code]  
  48. */  

但是如果尝试更改一个值,会得到一个错误:

  1. panic: reflect.Value.SetString using value obtained using unexported field 

这是因为结构中只有被导出字段(首字母大写)才是可设置的,来看下面的例子:

  1. // 示例代码9-9  
  2. package main  
  3.  
  4. import (  
  5.     "fmt"  
  6.     "reflect"  
  7. )  
  8.  
  9. type T struct {  
  10.     A int  
  11.     B string  
  12. }  
  13.  
  14. func main() {  
  15.     t :T{23, "Hello"}  
  16.     s :reflect.ValueOf(&t).Elem()  
  17.     typeOfT :s.Type()  
  18.     for i :0; i < s.NumField(); i++ {  
  19.         f :s.Field(i)  
  20.         fmt.Printf("%d: %s %s = %v\n", i,  
  21.             typeOfT.Field(i).Name, f.Type(), f.Interface())  
  22.     }  
  23.     s.Field(0).SetInt(77)  
  24.     s.Field(1).SetString("The World")  
  25.     fmt.Println("t现在的值是:", t)  
  26. }  
  27. /*  
  28. 返回:  
  29. 0: A int = 23 
  30. 1: B string = Hello 
  31. t现在的值是:{77 The World}  
  32. */  


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书会第9群:808517103

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

JSP应用开发详解(第三版)

本书结合JSP和Servlet的最新规范,从基本的语法和规范入手,以经验为后盾,以实用为目标,以实例为导向,以实践为指导,深入浅出地讲解了JS...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊