当前位置: 首页 > news >正文

Golang的结构体和反射

目录

结构体

声明

结构体的使用

结构体和json数据的互相转换

反射

变量内置pair结构

reflect包

获取字段的类型和值

获取结构体字段、方法的名称、类型和值

解析结构体标签Tag

结构体

声明

// 声明一种新的类型 myint,是int的别名
type myint int// 定义一个结构体:把多种基本数据类型组合到一起变成一个新的类型
type Book struct {title  stringauthor stringprice  myint
}func changeBook(book Book) {//传递的是值类型,所以修改的是副本,不会影响原来的变量book.price = 999
}func changeBook1(book *Book) {// 指针类型可以修改结构体变量的值book.author = "新作者"
}func main() {var a myint = 10fmt.Println("a =", a)fmt.Printf("type of a is %T\n", a)var book1 Bookbook1.title = "Go 语言"book1.author = "老子"book1.price = 299fmt.Println("book1 =", book1)fmt.Printf("type of book1 is %T\n", book1)changeBook(book1)fmt.Println("--------------")fmt.Println("book1 =", book1)changeBook1(&book1)fmt.Println("--------------")fmt.Println("book1 =", book1)
}=================================================
PS D:\GoProject\firstGoProject> go run firstGoProject.go
a = 10
type of a is main.myint
book1 = {Go 语言 老子 299}
type of book1 is main.Book
--------------
book1 = {Go 语言 老子 299}
--------------
book1 = {Go 语言 新作者 299}

结构体的使用

import "fmt"//如果类名首字母大写,表示其他包也可以访问
type Hero struct {//如果类的属性首字母大写,表示其他包也可以访问,否则只能在本包中访问Name  stringAd    intLevel int
}func (this Hero) GetName() string {return this.Name
}func (this Hero) SetName(newName string) {//当前this是调用该方法的对象的拷贝this.Name = newName
}func (this Hero) ShowInfo() {fmt.Println("hero = ", this)
}func (this *Hero) SetName1(newName string) {//这里的this是指针类型,所以可以修改对象的值this.Name = newName
}func main() {// create a Hero objecthero := Hero{Name: "Alice", Ad: 100, Level: 10}var name = hero.GetName()fmt.Println("name = ", name)hero.ShowInfo()hero.SetName("Bob")hero.ShowInfo()hero.SetName1("Charlie")hero.ShowInfo()
}
-----------------------------------------------------
PS D:\GoProject\firstGoProject> go run firstGoProject.go
name =  Alice
hero =  {Alice 100 10}
hero =  {Alice 100 10}
hero =  {Charlie 100 10}

结构体和json数据的互相转换

import ("encoding/json""fmt"
)type Movie struct {Title  string   `json:"title"`      //结构体的标签Year   int      `json:"year"`Price  int      `json:"price"`Actors []string `json:"actors"`
}func main() {movie := Movie{Title:  "The Dark Knight",Year:   2008,Price:  150,Actors: []string{"Christopher Nolan", "Robert Duvall"},}//编码的过程  结构体 --->  jsonjsonStr, err := json.Marshal(movie)if err != nil {fmt.Println("json marshal error", err)}fmt.Printf("jsonStr = %s\n", jsonStr)//解码的过程  json --->  结构体//jsonStr = {"title":"The Dark Knight","year":2008,"price":150,"actors":["Christopher Nolan","Robert Duvall"]}myMovie := Movie{}err = json.Unmarshal(jsonStr, &myMovie)if err != nil {fmt.Println("json unmarshal error", err)return}fmt.Printf("myMovie = %v\n", myMovie)}
PS D:\GoProject\firstGoProject> go run firstGoProject.go
jsonStr = {"title":"The Dark Knight","year":2008,"price":150,"actors":["Christopher Nolan","Robert Duvall"]}
myMovie = {The Dark Knight 2008 150 [Christopher Nolan Robert Duvall]}

反射

反射(Reflection) 是指在程序运行时可以访问、检测和修改其自身状态或行为的一种能力。
具体来说,在面向对象编程中,反射允许程序:

  1. 在运行时获取类型信息(类名、方法、属性、注解等)

  2. 动态调用方法或访问属性

  3. 构造对象(即使编译时不知道具体类)

  4. 检查并操作类成员

反射机制允许程序在运行时获取类型信息并动态调用成员,而不需要在编译时确定具体的类或方法。


变量内置pair结构

一个变量中含有type  和  value ,称作pair

type分为 static type  和 concrete type,变量的type是两者中的一个(不能同时有两个type) 

import "fmt"func main() {var a string//pair <type:static type(string), value:"Hello, World!">a = "Hello, World!"//pair <type:constant type, value: nil>var allType interface{}//pair <type:string, value:"Hello, World!">allType = astr, _ := allType.(string)fmt.Println(str)
}
-------------------------------------------------------
PS D:\GoProject\firstGoProject> go run firstGoProject.go
Hello, World!
import ("fmt""io""os"
)func main() {//tty: pair<type: *os.File, value: "/dev/tty" 文件描述符>tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)if err != nil {fmt.Println(err)return}//r: pair<type: ,value: >var r io.Reader//r: pair<type: *os.File, value: "/dev/tty" 文件描述符>r = tty//w: pair<type: ,value: >var w io.Writer//w: pair<type: *os.File, value: "/dev/tty" 文件描述符>w = r.(io.Writer)w.Write([]byte("Hello, world!\n")) // 向终端输出 "Hello, world!\n"
}
type Reader interface {ReadBook()
}type Writer interface {WriteBook()
}// 具体类型
type Book struct {
}func (this *Book) ReadBook() {fmt.Println("Reading book...")
}func (this *Book) WriteBook() {fmt.Println("Writing book...")
}func main() {// 接口变量 b:pair<type:Book,value:book{}地址>b := &Book{}// 接口变量 r:pair<type:,value:>var r Reader//此时r的类型为nilfmt.Printf("r: %T\n", r)//r:pair<type:Book,value:book{}地址>r = b// 调用接口方法r.ReadBook()var w Writerw = r.(Writer)w.WriteBook()
}-------------------------------------------------------------
PS D:\GoProject\firstGoProject> go run firstGoProject.go
r: <nil>
Reading book...
Writing book...

reflect包

获取字段的类型和值

import ("fmt""reflect"
)func reflectNum(arg interface{}) {fmt.Println("type :", reflect.TypeOf(arg))fmt.Println("value:", reflect.ValueOf(arg))
}func main() {var num float64 = 3.14reflectNum(num)
}
----------------------------------------------
PS D:\GoProject\firstGoProject> go run firstGoProject.go
type : float64
value: 3.14

获取结构体字段、方法的名称、类型和值

import ("fmt""reflect"
)type User struct {Id   intName stringAge  int
}func (this User) Call() {fmt.Println("user is called ..")fmt.Printf("%v\n", this)
}func main() {user := User{1, "John", 25}DoFileAndMethod(user)
}func DoFileAndMethod(input interface{}) {//获取input的类型inputType := reflect.TypeOf(input)fmt.Println("inputType is:", inputType.Name())//获取input的valueinputValue := reflect.ValueOf(input)fmt.Println("inputValue is:", inputValue)//通过type获取里面的字段//1. 获取interface的reflect.Type,通过Type得到NumField,进行遍历//2. 得到每个field,数据类型//3. 通过filed有一个Interface()方法等到 对应的valuefor i := 0; i < inputType.NumField(); i++ {field := inputType.Field(i)value := inputValue.Field(i).Interface()fmt.Printf("field = %s,type = %v, value = %v\n", field.Name, field.Type, value)}fmt.Println("--------------------", inputType.NumMethod())//通过type获取里面的方法,调用for i := 0; i < inputType.NumMethod(); i++ {m := inputType.Method(i)fmt.Printf("%s,%v\n", m.Name, m.Type)}
}
PS D:\GoProject\firstGoProject> go run firstGoProject.go
inputType is: User
inputValue is: {1 John 25}
field = Id,type = int, value = 1        
field = Name,type = string, value = John
field = Age,type = int, value = 25      
-------------------- 1
Call,func(main.User)

解析结构体标签Tag

import ("fmt""reflect"
)type resume struct {Name string `info:"name" doc:"我的名字"`Sex  string `info:"sex" doc:"我的性别"`
}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 resumefindTag(&re)
}
PS D:\GoProject\firstGoProject> go run firstGoProject.go
info: name doc: 我的名字
info: sex doc: 我的性别

http://www.dtcms.com/a/466941.html

相关文章:

  • 网站点击量软件古腾堡布局的网站
  • 网站title优化手机网页页面设计模板
  • 湛江正规网站制作方案网站建设五项基本原则
  • 【Vue】——路由
  • 160 国际英文网站app开发公司哪里好
  • 企业网站优化哪家好陕西住房与城乡建设部网站
  • 小模型大智慧:新一代轻量化语言模型全解析
  • 网站首页背景代码wordpress幻灯片不显示
  • 37.2多点电容触摸屏实验(详细代码)_csdn
  • 了解学习MySQL数据库基础
  • 做网站怎么选服务器服务器网站怎么做
  • 长沙微信网站开发学习网页制作学什么
  • 超越RTL的系统设计:ESL设计的新范式与CIRCT的桥梁作用
  • JVM的即时编译JIT的介绍
  • 网站建设心得8000字网站域名设计推荐
  • 十堰哪里有做网站的搜索引擎营销的案例有哪些
  • 网站空间流量不够服务器建网站
  • 长宁苏州网站建设公司cms系统表单
  • 化妆品营销型网站案例工商管理系统官网
  • 免费的推广网站有哪些wordpress 36kr 模板
  • 网站建设对企业的意义太白县住房和城乡建设局网站
  • 保山市住房和城乡建设厅网站搜索引擎网站建设
  • 【MySQL在Ubuntu系统下的安装方法】保姆级教程
  • 网站服务器怎么查询网站建设服务器怎么设置
  • 南京建设集团网站做好产品策划的重要性
  • ModStartCMS v9.7.0 组件升级优化,模块升级提醒,访问明细导出
  • 网站如何安装wordpress爆款采集推广引流软件
  • 双目测距实战2-相机标定过程
  • anthropics-claude-cookbooks学习记录01
  • 品网站建设河南省住房和城乡建设部网站首页