这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
整理了一下go平时经常用到的语法和函数
切片
切片不同于数组可以任意更改长度,然后也有更多丰富的操作。比如说我们可以用make 来创建一个切片,可以像数组一样去取值, 使用append来追加元素。切片可以用下标来操作,这一点类似于python,比如s[1,3],来截取s下标1到3的内容,左闭右开,如果起始位置或者结束位置没有写,s[:3], s[2:]就是从头开始或者一直到切片尾。
s := make( []string, 3)
s = append(s, "d")
结构体
结构体是带类型的字段的集合。 比如这里user结构包含了两个字段,name和pasword。一般的结构体字段名使用大写,表示公开,如果是小写,则使用JSON.marshaler()将结构体转为json时,会忽略该字段。
可以用结构体的名称去初始化一个结构体变量,构造的时候需要传入每个字段的初始值。也可以用这种键值对的方式去指定初始值,这样可以只对一部分字段进行初始化。同样的结构体我们也能支持指针,这样能够实现对于结构体的修改,也可以在某些情况下避免一些大结构体的拷贝开销。
package main
import "fmt"
type user struct {
name string
password string
}
func main() {
a := user{name : "wang" , password : "1024"}
b := user{ "wang", "1024"}
c := user{name: "wang"}
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
fmt.Println(a, b, c, d) // {wang 1024} {wang 1024]} {wang 1024} {wang 1024}
fmt.Println( checkPassword( a,"haha" )) // false
fmt.Println( checkPassword2(&a,"haha" )) // false
}
结构体方法
在Golang里面可以为结构体去定义一些方法。会有一点类以其他语言里面的类成员函数。比如这里,我们把上面一个例子的checkPaddword的实现。从一个普通函数,改成了结构体方法,这样用户可以像a.checkPassword("x")这样去调用。具体的代码修改,就是把第一个参数,加上括号,写到函数名称前面。 在实现结构体的方法的时候也有两种写法,一种是带指针,一种是不带指。这个它们的区别的话是说如果你带指计的话,那么你就可以对这个结的体去做修改。如果你不带指针的话,那实际上操作的是一个拷贝,你就无法对结构体进行修改。
package main
import "fmt"
type user struct {
name string
password string
}
func (u user ) checkPassword( password string) bool {
return u.password == password
}
func ( u *user ) resetPassword( password string) {
u. password = password
}
func main( ) {
a := user{name : "wang", password : "1024"}
a.resetPassword("2048")
fmt.Println( a.checkPassword( "2048" )) // true
}
比如函数 resetPassword需要修改结构体user的password字段,所以在定义方法时,需要带上指针。一般情况传结构体时,我们都会使用指针,方便能够在函数中修改传入的结构体。
JSON处理
go语言里面的JSON操作非常简单,对于一个已有的结构体,我们可以什么都不做,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用JSON.marshaler去序列化,变成一个JSON的字符串。
这样默认序列化出来的字符串的话,它的风格是大写字母开头。我们可以在后面用json tag等语法来去修改输出JSON结果里面的字段名,使其小写字母开头,符合驼峰命名。 go常用的操作数据库的第三方库xorm,在定义字段于数据库字段映射时,也是用这样的语法。
func query(word string) {
client := &http.Client{}
request := DictRequest{TransType: "en2zh", Source: word}
buf, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
同样的,在一个包中,方法首字母大写,则可以被别的包使用,如果方法名首字母小写,则只能在该包内使用。
序列化之后的字符串也能够用JSON.unmarshaler去反序列化到一个空的变量里面。
var dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
时间处理
time.now()获取当前时间 .sub函数可以对两个时间做减法,计算时间差。在判断accesstoken是否过期时,可以使用这个函数,计算当前时间和accesstoken过期时间的差。
now := time.Now()
fmt.Println(now) // 2022-03-27 18:04∶59.433297+0800 CST m=+0 .000087933t := time.Date( 2022,3,27,1,25,36,0, time.UTC)
t2 := time.Date(2022,3,27,2,30,36,0, time.UTC)fmt . Println(t) //2022-03-2701:25:36 +0000 UTC
fmt.Println ( t.Year(),t.Month(),t.Day(),t.Hour(),t.Minute()) // 2022 March 27 1 25
fmt.Println(t.Format( "2006-01-02 15:04:05" )) //2022-03-27 01:25:36
diff := t2.Sub( t)