Go基础学习(部分)
Go基础学习
Go的下载源GOPROXY=https://goproxy.cn,direct
1.文件操作
文件操作有三个库,os
,bufio
,ioutil
注意点就是prem参数
r
读权限w
写权限x
执行权限-
不具有该权限rwx
==> 111rw-
==> 110r--
==> 100---
==> 000
destFile, err := os.OpenFile(destFileName, os.O_WRONLY|os.O_CREATE, 0666)
例如这里的0666
就是八进制数字,拆为二进制数的时候是110110110
,也就是rw-rw-rw-
,这里就赋予了文件读和写的权限
2.文件打开模式:
const (
O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
O_RDWR int = syscall.O_RDWR // 读写模式打开文件
O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件
O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在
O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/O
O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件
)
2.结构体的tag标签
注意:在go语言中,首字母大写是公有的,首字母小写是私有的,所以在进行跨文件编写的时候,要将字段名设置为首字母大写的,但是对于json
类型的数据来说,有的时候小写首字母是有必要的
package main
import (
"encoding/json"
"fmt"
)
type Monster struct {
Name string `json:"name"`
Age int `json:"age"`
Skill string `json:"skill"`
}
func (Monster) testMarshal(name string, age int, skill string) {
mos := Monster{Name: name, Age: age, Skill: skill}
data, err := json.Marshal(mos) // json的序列化
var monster Monster
json.Unmarshal(data, &monster) // json的反序列化
fmt.Println(monster.Name + "" + monster.Skill)
fmt.Printf("data is %s\n", data)
}
func main() {
mos := Monster{}
mos.testMarshal("feng", 12, "pk")
}
3.反射
通过接受Interface{}
类型的数据来反射出输入的变量的type
,kind
,value
下面的是基本类型的反射案例
package main
import (
"fmt"
"reflect"
)
func testReflect(b interface{}) {
rType := reflect.TypeOf(b)
fmt.Println(rType)
rVal := reflect.ValueOf(b)
fmt.Println(rVal)
n1 := rVal.Int() + 2 // 只有对应的类型才能进行对应的操作
fmt.Println(n1)
iV := rVal.Interface()
num2 := iV.(int) // 类型断言
fmt.Println(num2)
}
func main() {
i := 100
testReflect(i)
}
下面的是结构体的反射
package main
import (
"fmt"
"reflect"
"strconv"
)
type Student struct {
Name string
Age int
}
func testReflect(b interface{}) {
rType := reflect.TypeOf(b)
fmt.Println(rType)
rVal := reflect.ValueOf(b)
fmt.Println(rVal)
rKind1 := rVal.Kind()
rKind2 := rVal.Kind() // kind的范围大于type
fmt.Printf("rKind1 is %T\n,rKind2 is %T\n", rKind1, rKind2) // reflect.Kind
iV := rVal.Interface()
fmt.Printf("%T\n,%v\n", iV, iV) // main.Student
data, _ := iV.(Student) // 类型断言
fmt.Println(strconv.FormatInt(int64(data.Age), 10) + data.Name)
}
func main() {
student := Student{Name: "feng", Age: 18}
testReflect(student)
}
go语言的强转类型是b := int64(var a string)
这样的形式
注意事项
package main
import (
"fmt"
"reflect"
)
func testReflect(b interface{}) {
rVal := reflect.ValueOf(b)
rValElem := rVal.Elem() // 获取对应的地址中的值,通过这个就可以实现了修改值
rValElem.SetInt(200)
fmt.Println(rValElem)
}
func main() {
num := 100
testReflect(&num)
}
反射的最佳应用
package main
import (
"fmt"
"reflect"
"src/pkg"
)
func testReflect(b interface{}) {
rVal := reflect.ValueOf(b)
rType := reflect.TypeOf(b)
fmt.Println(rVal.NumField())
for i := 0; i < rVal.NumField(); i++ {
fmt.Println(rVal.Field(i))
fmt.Println(rType.Field(i).Tag.Get("json")) // 获得对应结构体json的字段名
}
fmt.Println(rVal.NumMethod())
fmt.Printf("%T", reflect.Value{})
for i := 0; i < rVal.NumMethod(); i++ { // 函数名字进行排序
method := rVal.Method(i)
params := []reflect.Value{}
params = append(params, reflect.ValueOf(20))
params = append(params, reflect.ValueOf(40))
fmt.Println(method.Call(params)[0].Int())
}
}
func testReflect1(b interface{}) {
rVal := reflect.ValueOf(b)
fmt.Println(rVal.Elem().NumField())
rVal.Elem().Field(0).SetString("xcq") // 这里的循环遍历修改可以通过类型断言实现
for i := 0; i < rVal.Elem().NumField(); i++ {
fmt.Println(rVal.Elem().Field(i))
}
}
func main() {
student := pkg.Student{Name: "feng", Age: 18}
testReflect(student)
testReflect1(&student) // 传入地址,进行修改值
}
4.类型断言
value,ok := x.(T)
x是一个接口类型,T是一个具体的类型(也可称为接口类型),value是这个接口的值,ok是这个转类型的依据之后的一个布尔值
package main
import (
"fmt"
)
func main() {
var x interface{}
x = 10
value, ok := x.(int)
if ok == false {
fmt.Println("错误了")
} else if ok == true{
fmt.Print(value, ",", ok)
}
}
类型断言一般搭配switch
语句来使用
package main
import (
"fmt"
)
func main() {
var a int
a = 10
getType(a)
}
func getType(a interface{}) {
switch a.(type) {
case int:
fmt.Println("the type of a is int")
case string:
fmt.Println("the type of a is string")
case float64:
fmt.Println("the type of a is float")
default:
fmt.Println("unknown type")
}
}
注意:空的interface
是可以接纳任何类型的数据的