go基础语法 | 青训营笔记

77 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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:0459.433297+0800 CST m=+0 .000087933t := time.Date( 2022327125360, time.UTC)
t2 := time.Date(2022327230360, 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)