Go基础学习(部分)

Go基础学习

Go的下载源GOPROXY=https://goproxy.cn,direct

Go的学习文档 最好的学Go的网站

1.文件操作

文件操作有三个库,os,bufio,ioutil

注意点就是prem参数

  • r读权限
  • w 写权限
  • x 执行权限
  • - 不具有该权限
  • rwx ==> 111
  • rw- ==> 110
  • r-- ==> 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是可以接纳任何类型的数据的

posted @ 2022-04-25 20:18  xcq保护我  阅读(48)  评论(0编辑  收藏  举报