文章目录
包管理
change.go
package ch1
import "fmt"
//ch1 声明一个struct
type Person struct {
Name string
Sex string
Age int
}
tempchange.go
package ch1
//不同文件 同包名 对Person结构体(*Perwson 指针类型) 创建方法 Work
import "fmt"
//Work 需要大写 用于可暴露可访问
func (p *Person) Work(x string) string {
return fmt.Sprintf("%v岁的%v性%v的工作是%v", p.Age, p.Sex, p.Name, x)
}
package main
import (
"fmt"
myPkg "testPkg/gopl.io/ch1"
)
//main包中 导入重命名 myPkg(ch1)
func main() {
v := myPkg.Person{
Name: "张三",
Age: 12,
Sex: "男",
}
//调用指针类型的 Person结构体的实例方法 Work
fmt.Println((&v).Work("干饭"))
}
1.序列化
Marshal
func Marshal(v interface{})([]byte,error)
package main
import (
"encoding/json"
"fmt"
)
func main() {
p := Person{Name: "小王", Age: 12}
data, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
} else {
//返回一个[]byte//使用string转换//{"Name":"小王","Age":12}
fmt.Println(string(data))
}
}
type Person struct {
Name string
Age int
}
2.反序列化
Unmarshal
func Unmarshal([]byte,*type)
package main
import (
"encoding/json"
"fmt"
)
func main() {
p := Person{Name: "小王", Age: 12}
data, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(string(data))
}
var b Person
json.Unmarshal(data, &b)
fmt.Println(b)
//反序列化
}
type Person struct {
Name string
Age int
}
反射
reflect
import "reflect"
1.反射可以在运行时动态获取变量的各种信息,比如变量的类型(type),类别(kind)
2.如果是结构体变量,还可以获取结构体本身的信息(包括结构体的字段、方法)
1、reflect.TypeOf()和reflect.ValueOf()
interface{}类型变量其具体类型可以使用reflect.Tpye来表示,而其具体值则使用reflect.Value来表示。而reflect.Type和reflect.Value分别提供reflect.TypeOf()和reflect.ValueOf()来获取interface{}的具体类型及具体值。
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customeId int
}
func query(i interface{}) {
t := reflect.TypeOf(i)
v := reflect.ValueOf(i)
fmt.Println(t)
fmt.Println(v)
}
func main() {
o := order{
ordId: 1,
customeId: 2,
}
query(o)
//main.order
//{1 2}
}
2、reflect.Kind()//获取的是底层类型(struct、ptr等)
reflect.Name()获取的是类型名称
import (
"fmt"
"reflect"
)
func reflectFn(i interface{}) {
v := reflect.TypeOf(i)
fmt.Println(reflect.ValueOf(i))
fmt.Println("v.Name():", v.Name()) //
fmt.Println("v.Kind():", v.Kind())
}
type Person struct {
name string
}
func main() {
p := Person{name: "123"}
var h = 25
reflectFn(&h) // Name Person Kind Struct
reflectFn(p)
}
0xc0000a6058
v.Name():
v.Kind(): ptr
&{123}
v.Name():
v.Kind(): ptr
在reflect还有一个比较重要的类型Kind,也是代表类型,看起来和我们前面提到的reflect.Type很相似,其实两者有着很大的差异:
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customeId int
}
func query(i interface{}) {
t := reflect.TypeOf(i)
v := reflect.ValueOf(i)
k := t.Kind()
fmt.Println(t)
fmt.Println(v)
fmt.Println(k)
}
func main() {
o := order{
ordId: 1,
customeId: 2,
}
query(o)
//main.order
//{1 2}
//struct
}
通过输出结果我们能够很清楚的看出来reflect.Type和reflect.Kind:Type代表interface{}实际类型main.order;而Kind代表具体类型struct。
3、NumField() 和Field()
NumField()方法获取一个struct所有的fields,Field(i int)获取指定第i个field的reflect.Value,结合具体实例:
package main
import (
"fmt"
"reflect"
)
type order struct {
ordId int
customeId int
}
func query(i interface{}) {
t := reflect.TypeOf(i)
v := reflect.ValueOf(i)
k := t.Kind()
fmt.Println(t)
fmt.Println(v)
fmt.Println(k)
if reflect.ValueOf(i).Kind() == reflect.Struct {
value := reflect.ValueOf(i) //获取i的值
fmt.Println("Number of fields", value.NumField()) //获取字段总个数
for j := 0; j < value.NumField(); j++ {
fmt.Printf("Field:%d type:%T value:%v\n", j, v.Field(j), v.Field(j)) //获取第j个字段的 reflect.Value的类型 和reflect.value
}
}
}
func main() {
o := order{
ordId: 1,
customeId: 2,
}
query(o)
//main.order
//{1 2}
//struct
//Number of fields 2
//Field:0 type:reflect.Value value:1
//Field:1 type:reflect.Value value:2
}
4、Int() 和String()
Int()和String()主要用于从reflect.Value提取对应值作为int64和string类型
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)
}
//type:int64 value:56
//type:string value:Naveen
示例:
package main
import (
"fmt"
"reflect"
)
type person struct {
name string
age int
}
func main() {
p := person{
name: "嚣张",
age: 123,
}
fmt.Println(reflect.TypeOf(p))
fmt.Println(reflect.ValueOf(p).Kind())
x := reflect.ValueOf(p)
fmt.Println(x.NumField())//reflect.Value的字段个数
fmt.Println(x.Field(0))//reflect.Value第一个字段的值
fmt.Println(x.Field(1))//第二个字段的值
fmt.Printf("%T", x.Field(1))//打印第二个字段的值类型//
fmt.Printf("%T",x.Field(1).String())//使用String()转类型
}
main.person
struct
2
嚣张
123
reflect.Value
string
1.interface{}类型的值到反射reflecton对象.
根源上来说, reflection的原理就是检查interface中保存的一对值和类型, 所以在reflect包中,有两个类型我们需要记住, Type和Value两个类型. 通过这两个类型,我们可以访问一个interface变量的内容. 调用reflect.ValueOf和reflect.TypeOf可以检索出一个interface的值和具体类型. 当然通过reflect.Value我们也可以获得reflect.Type。
2.反射reflection对象到interface{}类型的值.
通过reflect.Value的Interface方法,我们可以获得一个Interface值。实际上这个方法将一个type和value打包回interface
3.当修改一个反射reflection时, 其值必须是settable.
5.Elem()
当传入的是一个指针类型时候
使用Elem()获取具体的元素值
package main
import (
"fmt"
"reflect"
)
func reflectSetValue1(x interface{}) {
//var a = reflect.ValueOf(x)//ptr 获取到的是指针
//if a.Kind() == reflect.Int64 {
// a.SetInt(120)
//}
v := reflect.ValueOf(x)
fmt.Println(v)//ptr 获取到的是指针
//v.Elem()获取具体的元素值.Kind()获取类型
if v.Elem().Kind() == reflect.Int64 {
//使用setInt修改
v.Elem().SetInt(123)
}
}
func reflectSetValue2(x interface{}) {
}
func main() {
var a int64 = 100
reflectSetValue1(&a)//传入指针
fmt.Println(a)
}
文件操作
读取
1.os.Open//只读方式打开文件
package main
import (
"fmt"
"io"
"os"
)
func main() {
//绝对路径
//os.Open("E:/GO/demo03/main.go")
//相对路径
file, err := os.Open("E:/GO/demo03/main.go")
defer file.Close()
if err != nil {
fmt.Println("打开文件失败", err)
return
}
fmt.Println(file)
//2读取文件里面的记录
var tempSlice = make([]byte, 128) //
var strSlice []byte
for {
//
n, err := file.Read(tempSlice)
if err == io.EOF {
fmt.Println("读取完毕")
break
}
if err != nil {
fmt.Println("读取失败")
return
}
fmt.Println("读取到了", n, "字节")
strSlice = append(strSlice, tempSlice[:n]...)
}
fmt.Println(string(strSlice), "string")
}
2.bufio
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("E:/GO/demo01/main.go")
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
var fileStr string
//bufio读取文件
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n') //表示一次读取一行
if err == io.EOF {//读取完了可能还会返回io
fileStr += str
fmt.Println("文件读取完毕")
break
}
if err != nil {
fmt.Println("err=", err)
return
}
fmt.Println(str)
}
fmt.Println(fileStr)
}
3.readFile(小的简单的文件使用)
package main
import (
"fmt"
"os"
)
func main() {
str, err := os.ReadFile("E:/GO/deo02/main.go")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(str))
}
写入
方法1:
file.Write
package main
import (
"fmt"
"os"
)
// 第一种写入文件的方法
func main() {
file, err := os.OpenFile("E:/GO/README.txt", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
defer file.Close()
if err != nil {
fmt.Println("失败", err)
return
}
var str = "卧槽\n"
//写入文件[]byte
file.Write([]byte(str))
//写入文件 string
//file.WriteString(str)
}
方法2:
bufio操作写入
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("E:/GO/README.txt", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
var str = "你好222\n"
Writer := bufio.NewWriter(file) // bufio.NewWriter传入file对象,创建Writer对象
//Writer.WriteString(str) //将数据先写入缓存
Writer.Write([]byte(str))
Writer.Flush() //将缓存中的内容写入文件
}
方法2:
os.WriteFile(名字,byte类型切片,权限)
package main
import (
"fmt"
"os"
)
func main() {
//绝对路径
//os.Open("E:/GO/demo03/main.go")
//相对路径
var str = "你好 golang\n"
err := os.WriteFile("E:/GO/README.txt", []byte(str), 0666)
if err != nil {
fmt.Println("失败", err)
}
}
复制
第一种:os
package main
import (
"fmt"
"os"
)
func copy(srcFileName string, dstFileName string) (err error) {
//读取文件
byteStr, err := os.ReadFile(srcFileName)
if err != nil {
fmt.Println(err)
return err
}
err1 := os.WriteFile(dstFileName, byteStr, 0666)
if err1 != nil {
fmt.Println(err1)
return err1
}
fmt.Println("复制文件成功")
return nil
}
func main() {
copy("E:/GO/README.txt", "D:/README.txt")
}
第二种:
package main
import (
"fmt"
"io"
"os"
)
func copy(srcFileName string, dstFileName string) (err error) {
sFile1, err1 := os.Open(srcFileName)
defer sFile1.Close()
sFile2, err2 := os.OpenFile(dstFileName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)//创建 读写 追加
defer sFile2.Close()
if err1 != nil {
return err1
}
if err2 != nil {
return err2
}
var tempSlice = make([]byte, 128)
for {
//读取数据
n1, err := sFile1.Read(tempSlice)
if err == io.EOF {
fmt.Println("读取完成")
break
}
if err != nil {
return err
}
//写入数据
if _, err1 := sFile2.Write(tempSlice[:n1]); err1 != nil {
return err1
}
}
return nil
}
func main() {
copy("E:/GO/README.txt", "D:/README.txt")
}
创建文件夹
单个文件夹创建
err:=os.Mkdir("./abc",0666)//在当前目录创建文件夹abc
if err!=nil{
fmt.Println(err)
}
//重复创建
mkdir ./abc: Cannot create a file when that file already exists.
多级创建
err1 := os.MkdirAll("./dir1/dir2/dir3", 0666)
if err1 != nil {
fmt.Println(err1)
}
删除
删除文件和删除一个目录
package main
import (
"fmt"
"os"
)
func main() {
err := os.Remove("D:/README.txt")
if err != nil {
fmt.Println(err)
}
}
err := os.Remove("abc")
if err != nil {
fmt.Println(err)
}
删除所有的目录
err1 := os.RemoveAll("dir1")
if err1 != nil {
fmt.Println(err1)
}
重命名
err := os.Rename("D:/README.txt", "D:/README1.txt")
if err != nil {
fmt.Println(err)
}