Go语言基础 | 青训营笔记

392 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

1. 变量

常见的变量类型包括:字符串、整数、浮点型、布尔型等。

在go语言中声明变量有两种方式,一种方式是

var a = "initial"
​
var b, c int = 1, 2

声明变量时候,一般会自动推导变量的类型,如果有需要也可以显示写出变量类型。

另一种声明变量的方式是

f := float32(e)
​
g := a + "foo"

声明常量是将var改为const,go语言里面的常量没有确定的类型,会根据使用的上下文来自动确定类型。

2. 循环

在go里只有一种for循环,在循环中可以使用continue或break来继续或跳出循环。

for j := 7; j < 9; j++ {
        fmt.Println(j)
    }

3. switch

在go语言中,是不需要加入break的,在匹配到正确的case后就会结束switch语句。并且switch语句可以取代if else,可以在switch后不加任何的变量,然后再case里面写条件分支。

a := 2
    switch a {
    case 1:
        fmt.Println("one")
    case 2:
        fmt.Println("two")
    case 3:
        fmt.Println("three")
    case 4, 5:
        fmt.Println("four or five")
    default:
        fmt.Println("other")
    }

4. 数组

var a [5]int
a[4] = 100

5. 切片

切片不同于数组可以任意改变长度,可以用make创建

s := make([]string, 3)
    s[0] = "a"
    s[1] = "b"
    s[2] = "c"

可以用append给切片追加元素

s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s) // [a b c d e f]
fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5])  // [a b c d e]
fmt.Println(s[2:])  // [c d e f]

6. map

在其他语言中,又叫哈希表或字典,可以通过make创建

m := make(map[string]int)
m["one"] = 1
m["two"] = 2

map要指定两个类型,第一个是key的类型为string,第二个为value的类型为int。

7. range

对于slice或map来说,通常可以用range来遍历。

m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
    fmt.Println(k, v) // b 8; a A
}
for k := range m {
    fmt.Println("key", k) // key a; key b
}

循环回返回两个值,第一个是索引,第二个是对应位置的值。

8. 函数

go中变量类型是后置的。函数原生支持返回多个值,在实际业务中一般返回两个值,第一个是真正的返回结果,第二个是一个错误信息。

func exists(m map[string]string, k string) (v string, ok bool) {
    v, ok = m[k]
    return v, ok
}

9. 指针

指针的一个主要用处是对传入参数进行修改。

func add2ptr(n *int) {
    *n += 2
}
​
func main() {
    n := 5
    add2ptr(&n)
    fmt.Println(n) // 7
}

10. 结构体

type user struct {
    name     string
    password string
}
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}

结构体方法:

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
}

11. 错误处理

go语言能够清晰知道哪个函数返回了错误,并且能用简单的if else来处理。

在函数返回值类型后面可以加个error,代表函数可能会返回错误。

type user struct {
    name     string
    password string
}
​
func findUser(users []user, name string) (v *user, err error) {
    for _, u := range users {
        if u.name == name {
            return &u, nil
        }
    }
    return nil, errors.New("not found")
}
​
func main() {
    u, err := findUser([]user{{"wang", "1024"}}, "wang")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(u.name) // wangif u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
        fmt.Println(err) // not found
        return
    } else {
        fmt.Println(u.name)
    }
}

12. JSON处理

对于一个已有的结构体,只要保证每个字段的第一个字母是大写,那么这个结构体就能用JSON.marshaler去序列化,变成一个JSON的字符串,序列化的字符串也能用JSON.unmarshaler去序列化到一个空的变量中。

type userInfo struct {
    Name  string
    Age   int `json:"age"`
    Hobby []string
}
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
if err != nil {
    panic(err)
}
fmt.Println(buf)         // [123 34 78 97...]
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}