目录标题
- 一、Reflection反射
-
- 1. What is reflection? 什么是反射
- 2. Inspect a variable and find its type 检查变量并找到它的类型
- 3. Reflect.Type and reflect.Value 反射类型和值
- 4. Reflect.Kind 查看底层种类
- 5. NumField() and Field() methods 字段数量和索引值方法
- 6. Int() and String() methods 整型和字符型方法
- 7. Complete Program 完整示例
- 二、 Reading Files
-
- 1. Reading Files 读取文件
- 2. Using absolute file path 使用绝对路径
- 3. Passing the file path as a command line flag 将文件路径作为命令行标志传递
- 4. Reading a file in small chunks
- 5. Reading a file line by line 逐行读取文件
一、Reflection反射
1. What is reflection? 什么是反射
反射是Go中的高级主题之一,在Go语言中反射(reflection)是指在程序运行时动态地检查类型信息和操作对象的能力。通过反射,你可以在运行时获取类型的信息,访问和修改对象的字段和方法,以及动态地调用函数。 Go语言中的反射由reflect包提供支持。该包中的Type和Value类型提供了访问和操作类型和对象的方法。
要使用反射,首先需要使用reflect.TypeOf()函数获取一个值的类型信息,或者使用reflect.ValueOf()函数获取一个值的反射对象。这些函数返回的类型对象或值对象包含了有关值的类型、字段、方法等信息。
反射对象的常用方法包括:
Type.Kind():返回类型的种类,如整数、字符串、结构体等。
Type.Name():返回类型的名称。
Type.Field(i int):返回结构体类型的第i个字段的反射对象。
Type.NumField():返回结构体类型的字段数量。
Value.Interface():将反射对象转换为普通的接口类型。
Value.Kind():返回值的种类,如整数、字符串、结构体等。
Value.String():返回值的字符串表示。
Value.Field(i int):返回结构体类型值的第i个字段的反射对象。
Value.NumField():返回结构体类型值的字段数量。
Value.Method(i int):返回值的第i个方法的反射对象。
Value.Call(args []Value):调用值对应的方法,传递参数并返回结果。
通过使用这些方法,你可以在运行时检查和操作任意类型的对象。例如,你可以获取一个结构体类型的字段名和值,动态调用函数,或者创建新的对象。
2. Inspect a variable and find its type 检查变量并找到它的类型
package main
import (
"fmt"
)
type order struct {
ordId int
customerId int
}
type employee struct {
name string
id int
address string
salary int
country string
}
func createQuery(b order) string {
i := fmt.Sprintf("insert into order values(%d, %d)", b.ordId, b.customerId)
return i
}
func createQuerySet(b employee) string {
i := fmt.Sprintf("insert into order values(%s, %d, %s, %d, %s)", b.name, b.id, b.address, b.salary, b.country)
return i
}
func main() {
a := 10
fmt.Printf("%d, %T\n", a, a)
b := order{
171103,
1006,
}
e := employee{
"Like",
1,
"Shanghai",
999999,
"Minghang",
}
fmt.Println(createQuery(b))
fmt.Println(createQuerySet(e))
}
3. Reflect.Type and reflect.Value 反射类型和值
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customerId int
}
func createQuery(q interface{}) {
t := reflect.TypeOf(q)
v := reflect.ValueOf(q)
fmt.Println("Type ", t)
fmt.Println("Value ", v)
}
func main() {
o := order{
ordId: 456,
customerId: 56,
}
createQuery(o)
}
4. Reflect.Kind 查看底层种类
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customerId int
}
func createQuery(q interface{}) {
t := reflect.TypeOf(q)
k := t.Kind()
fmt.Println("Type ", t)
fmt.Println("Kind ", k)
}
func main() {
o := order{
ordId: 456,
customerId: 56,
}
createQuery(o)
}
5. NumField() and Field() methods 字段数量和索引值方法
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customerId int
}
func createQuery(q interface{}) {
if reflect.ValueOf(q).Kind() == reflect.Struct {
v := reflect.ValueOf(q)
fmt.Println("Number of fields", v.NumField())
for i := 0; i < v.NumField(); i++ {
fmt.Printf("Field:%d type:%T value:%v\n", i, v.Field(i), v.Field(i))
}
}
}
func main() {
o := order{
ordId: 456,
customerId: 56,
}
createQuery(o)
}
6. Int() and String() methods 整型和字符型方法
package main
import (
"fmt"
"reflect"
)
func main() {
a := 56
x := reflect.ValueOf(a).Int()
fmt.Printf("type:%T value:%v\n", x, x)
b := "Naveen"
y := reflect.ValueOf(b).String()
fmt.Printf("type:%T value:%v\n", y, y)
}
7. Complete Program 完整示例
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customerId int
}
type employee struct {
name string
id int
address string
salary int
country string
}
func createQuery(q interface{}) {
if reflect.ValueOf(q).Kind() == reflect.Struct {
t := reflect.TypeOf(q).Name()
query := fmt.Sprintf("insert into %s values(", t)
v := reflect.ValueOf(q)
for i := 0; i < v.NumField(); i++ {
switch v.Field(i).Kind() {
case reflect.Int:
if i == 0 {
query = fmt.Sprintf("%s%d", query, v.Field(i).Int())
} else {
query = fmt.Sprintf("%s, %d", query, v.Field(i).Int())
}
case reflect.String:
if i == 0 {
query = fmt.Sprintf("%s\"%s\"", query, v.Field(i).String())
} else {
query = fmt.Sprintf("%s, \"%s\"", query, v.Field(i).String())
}
default:
fmt.Println("Unsupported type")
return
}
}
query = fmt.Sprintf("%s)", query)
fmt.Println(query)
return
}
fmt.Println("unsupported type")
}
func main() {
o := order{
ordId: 456,
customerId: 56,
}
createQuery(o)
e := employee{
name: "Naveen",
id: 565,
address: "Coimbatore",
salary: 90000,
country: "India",
}
createQuery(e)
i := 90
createQuery(i)
}
二、 Reading Files
1. Reading Files 读取文件
package main
import (
"fmt"
"os"
)
func main() {
contents, err := os.ReadFile("test.txt")
if err != nil {
fmt.Println("File reading error", err)
return
}
fmt.Println("Contents os file:", string(contents))
}
2. Using absolute file path 使用绝对路径
package main
import (
"fmt"
"os"
)
func main() {
contents, err := os.ReadFile("D:/Go/oop/test.txt")
if err != nil {
fmt.Println("File reading error", err)
return
}
fmt.Println("Contents os file:", string(contents))
}
3. Passing the file path as a command line flag 将文件路径作为命令行标志传递
package main
import (
"flag"
"fmt"
)
func main() {
fptr := flag.String("fpath", "test.txt", "file path to read from")
flag.Parse()
contents, err := os.ReadFile(*fptr)
if err != nil {
fmt.Println("File reading error", err)
return
}
fmt.Println("Contents of file: ", string(contents))
}
4. Reading a file in small chunks
package main
import (
"bufio"
"flag"
"fmt"
"io"
"log"
"os"
)
func main() {
targetPath := flag.String("targetPath", "test.txt", "file path to read from")
flag.Parse()
f, err := os.Open(*targetPath)
if err != nil {
log.Fatal(err)
}
defer func() {
if err = f.Close(); err != nil {
log.Fatal(err)
}
}()
r := bufio.NewReader(f)
b := make([]byte, 3)
for {
n, err := r.Read(b)
if err == io.EOF {
fmt.Println("Finished reading file")
break
}
if err != nil {
fmt.Println("Error %s reading files", err)
break
}
fmt.Println(string(b[0:n]))
}
}
5. Reading a file line by line 逐行读取文件
package main
import (
"bufio"
"flag"
"fmt"
"log"
"os"
)
func main() {
fptr := flag.String("fpath", "test.txt", "file path to read from")
flag.Parse()
f, err := os.Open(*fptr)
if err != nil {
log.Fatal(err)
}
defer func() {
if err = f.Close(); err != nil {
log.Fatal(err)
}
}()
s := bufio.NewScanner(f)
for s.Scan() {
fmt.Println(s.Text())
}
err = s.Err()
if err != nil {
log.Fatal(err)
}
}