1.反射
Go语言的变量分两部分,类型信息和值信息
在Go的反射机制中,任何接口值都是由一个具体类型和具体类型的值两部分组成
reflect.TypeOf和reflect.ValueOf两个重要的函数来获取任意对象的type和value
| v:=reflect.TypeOf(x) |
| v.Name() |
| v.Kind() |
指针类型的类型名称为空,类型种类为ptr,对象的类型种类是struct
数组类型的类型名称是空,类型种类是array
切片的类型名称是空,类型种类是slice
| |
| v := reflect.ValueOf(x) |
| var m = v.Int() + 12 |

如果传入的是一个地址,想要修改值的话,就需要加一个Elem()
v.Elem().Kind() // 获取值

| func printStruct(s interface{}) { |
| fmt.Println(reflect.TypeOf(s).Kind()) |
| fmt.Println(reflect.ValueOf(s).Kind()) |
| } |
| |
| func main() { |
| a := "hello" |
| printStruct(a) |
| } |
获取结构体字段:
| type Student struct { |
| Name string `json:"name" form:"username"` |
| Age int `json:"age"` |
| Score int `json:"score"` |
| } |
| |
| func main() { |
| stu := Student{ |
| Name: "Hello", |
| Age: 3, |
| Score: 100, |
| } |
| t := reflect.TypeOf(stu) |
| v := reflect.ValueOf(stu) |
| |
| field0 := t.Field(0) |
| fmt.Printf("%#v \n", field0) |
| fmt.Println("字段名称", field0.Name) |
| fmt.Println("字段类型", field0.Type) |
| fmt.Println("字段Tag:", field0.Tag.Get("json")) |
| fmt.Println("字段Tag:", field0.Tag.Get("form")) |
| |
| field1, ok := t.FieldByName("Age") |
| if ok { |
| fmt.Printf("%#v \n", field1) |
| fmt.Println("字段名称", field1.Name) |
| fmt.Println("字段类型", field1.Type) |
| fmt.Println("字段Tag:", field1.Tag.Get("json")) |
| } |
| |
| |
| fieldCount := t.NumField() |
| fmt.Println("结构体有多少个", fieldCount, "个属性") |
| |
| |
| fmt.Println(v.FieldByName("Name")) |
| fmt.Println(v.FieldByName("Age")) |
| |
| for i := 0; i < fieldCount; i++ { |
| fmt.Printf("属性名称:%v 属性值:%v 属性类型:%v 属性Tag:%v\n", t.Field(i).Name, v.Field(i), t.Field(i).Type, |
| t.Field(i).Tag.Get("json")) |
| } |
| } |
获取结构体方法:
| |
| |
| |
| |
| |
| package main |
| |
| import ( |
| "fmt" |
| "reflect" |
| ) |
| |
| |
| |
| |
| |
| |
| type Student struct { |
| Name string `json:"name" form:"username"` |
| Age int `json:"age"` |
| Score int `json:"score"` |
| } |
| |
| func (s Student) SayHello() { |
| fmt.Println("123456") |
| } |
| func (s Student) SayWorld(addr string, time string) { |
| fmt.Println(addr + time) |
| } |
| |
| func reflectChange(s interface{}) { |
| t := reflect.TypeOf(s) |
| v := reflect.ValueOf(s) |
| if t.Kind() != reflect.Ptr { |
| fmt.Println("传入的不是结构体指针类型") |
| return |
| } else if t.Elem().Kind() != reflect.Struct { |
| fmt.Println("传入的不是结构体指针类型") |
| return |
| } |
| |
| name := v.Elem().FieldByName("Name") |
| name.SetString("小李") |
| |
| age := v.Elem().FieldByName("Age") |
| age.SetInt(22) |
| } |
| |
| func main() { |
| v := Student{ |
| Name: "Hello", |
| Age: 3, |
| Score: 100, |
| } |
| a := reflect.ValueOf(v) |
| b := a.MethodByName("SayHello") |
| b.Call(nil) |
| |
| |
| var params []reflect.Value |
| params = append(params, reflect.ValueOf("新西兰")) |
| params = append(params, reflect.ValueOf("今年")) |
| a.MethodByName("SayWorld").Call(params) |
| |
| |
| fmt.Println("方法数量", a.NumMethod()) |
| |
| |
| reflectChange(&v) |
| fmt.Printf("%#v\n", v) |
| } |
反射是一个强大的工具,可以写出更灵活的代码,但是反射不应该被滥用
因为:
- 基于反射的代码是极其脆弱,反射中的类型错误会在真正运行的时候才会引发panic,哪可能是在写完代码很长时间之后
- 大量使用反射的代码通常难以理解
2.文件操作
文件读操作:
| package main |
| |
| import ( |
| "bufio" |
| "fmt" |
| "io" |
| "os" |
| ) |
| |
| func main() { |
| |
| |
| |
| |
| file, err := os.Open("./main.go") |
| defer file.Close() |
| if err != nil { |
| fmt.Println(err) |
| return |
| } |
| |
| var strSlice []byte |
| var tempSlice = make([]byte, 128) |
| for { |
| n, err := file.Read(tempSlice) |
| if err == io.EOF { |
| fmt.Println("读取完毕") |
| break |
| } |
| if err != nil { |
| fmt.Println("读取失败") |
| return |
| } |
| |
| |
| |
| strSlice = append(strSlice, tempSlice[:n]...) |
| fmt.Println(string(tempSlice)) |
| } |
| |
| |
| file, err = os.Open("./main.go") |
| defer file.Close() |
| if err != nil { |
| fmt.Println(err) |
| return |
| } |
| |
| var fileStr string |
| reader := bufio.NewReader(file) |
| for { |
| str, err := reader.ReadString('\n') |
| if err == io.EOF { |
| fileStr += str |
| break |
| } |
| if err != nil { |
| fmt.Println(err) |
| return |
| } |
| fmt.Println(str) |
| fileStr += str |
| } |
| fmt.Println(fileStr) |
| |
| |
| |
| } |
文件写操作:
| package main |
| |
| import ( |
| "bufio" |
| "fmt" |
| "os" |
| "strconv" |
| ) |
| |
| func main() { |
| |
| |
| |
| |
| file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666) |
| defer file.Close() |
| if err != nil { |
| fmt.Println(err) |
| return |
| } |
| |
| for i := 0; i < 10; i++ { |
| file.WriteString("直接写入的字符串数据" + strconv.Itoa(i) + "\r\n") |
| } |
| |
| |
| var str = "直接写入byte" |
| file.Write([]byte(str)) |
| |
| |
| Writer := bufio.NewWriter(file) |
| for i := 0; i < 10; i++ { |
| Writer.WriteString("你好golang") |
| } |
| Writer.Flush() |
| } |
文件复制、删除、重命名操作:
| package main |
| |
| import ( |
| "fmt" |
| "io" |
| "os" |
| ) |
| |
| func CopyFile(srcFileName string, dstFileName string) (err error) { |
| sFile, err1 := os.Open(srcFileName) |
| defer sFile.Close() |
| dFile, err2 := os.OpenFile(dstFileName, os.O_CREATE|os.O_WRONLY, 0666) |
| defer dFile.Close() |
| if err1 != nil { |
| return err1 |
| } |
| if err2 != nil { |
| return err2 |
| } |
| var tempSlice = make([]byte, 128) |
| for { |
| |
| n1, e1 := sFile.Read(tempSlice) |
| if err == io.EOF { |
| break |
| } |
| if e1 != nil { |
| return e1 |
| } |
| |
| _, e2 := dFile.Write(tempSlice[:n1]) |
| if e2 != nil { |
| return e2 |
| } |
| } |
| return nil |
| } |
| |
| func main() { |
| |
| srcFile := "./test.txt" |
| dstFile := "./target.txt" |
| err := CopyFile(srcFile, dstFile) |
| if err != nil { |
| fmt.Printf("拷贝完成\n") |
| } else { |
| fmt.Printf("拷贝错误 err=%v\n", err) |
| } |
| |
| |
| err1 := os.Mkdir("./abc", 0666) |
| |
| if err1 != nil { |
| fmt.Println(err) |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| err = os.Rename("./test.txt", "./hello.txt") |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Println("重命名成功") |
| } |
本文作者:oaoa
本文链接:https://www.cnblogs.com/oaoa/p/17299750.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步