go语言基础| 青训营笔记

41 阅读1分钟
title: go基础
date: 2023-5-12

什么是go语言

image-20230512202216548

变量常量

命名必须以一个字母或下划线开头

变量的声明

var a = "initial"var b, c int = 1, 2var d = truevar e float64
​
f := float32(e)
​
g := a + "foo"

常量的声明

const s string = "constant"
​
const h = 500000000
​
const i = 3e20 / h

new函数

表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T

p := new(int)   // p, *int 类型, 指向匿名的 int 变量
fmt.Println(*p) // "0"
*p = 2              // 设置 int 匿名变量的值为 2
fmt.Println(*p) // "2"

new函数类似是一种语法糖,而不是一个新的基础概念

func newInt() *int {
    return new(int)
}
// 这两个newInt函数有着相同的行为
func newInt() *int {
    var dummy int
    return &dummy
}

赋值

x = 1                                    // 命名变量的赋值
*p = true                             // 通过指针间接赋值
person.name = "bob"         // 结构体字段赋值
count[x] = count[x] * scale // 数组、slice或map的元素赋值

基础语法

  • if else

    if num := 9; num < 0 {
            fmt.Println(num, "is negative")
        } else if num < 10 {
            fmt.Println(num, "has 1 digit")
        } else {
            fmt.Println(num, "has multiple digits")
        }
    
  • switch

    a := 2
        switch a {
        case 1:
            fmt.Println("one")
        case 4, 5:
            fmt.Println("four or five")
        default:
            fmt.Println("other")
        }
    ​
        t := time.Now()
        switch {
        case t.Hour() < 12:
            fmt.Println("It's before noon")
        default:
            fmt.Println("It's after noon")
        }
    
  • 数组

    数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成

    在数组字面值中,如果在数组的长度位置出现的是“...”省略号,则表示数组的长度是根据初始化值的个数来计算。

    q := [...]int{1, 2, 3}
    fmt.Printf("%T\n", q) // "[3]int"
    

    因为数组的长度是固定的,因此在Go语言中很少直接使用数组

    func main(){
        var a [5]int
        a[4] = 100
        var twoD [2][3]int
        for i := 0; i < 2; i++ {
            for j := 0; j < 3; j++ {
                twoD[i][j] = i + j
            }
        }
    }
    
  • 切片

    切片代表变长的序列,序列中每个元素都有相同的类型

    func main() {
        
        s := make([]string, 3)
        s[0] = "a"
        s[1] = "b"
        s[2] = "c"
        fmt.Println("get:", s[2])   // c
        fmt.Println("len:", len(s)) // 3
    ​
        s = append(s, "d")
        s = append(s, "e", "f")
        fmt.Println(s) // [a b c d e f]
    ​
        c := make([]string, len(s))
        copy(c, s)
        fmt.Println(c) // [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]
    ​
        good := []string{"g", "o", "o", "d"}
        fmt.Println(good) // [g o o d]
    }
    

    测试一个slice是否是空的,使用len(s) == 0来判断,而不应该用s == nil来判断

    var s []int    // len(s) == 0, s == nil
    s = nil        // len(s) == 0, s == nil
    s = []int(nil) // len(s) == 0, s == nil
    s = []int{}    // len(s) == 0, s != nil=
    
  • map

    map是一个无序的key/value对的集合,其中所有的key都是不同的,然后通过给定的key可以在常数时间复杂度内检索、更新或删除对应的value

    func main() {
        //内置的make函数可以创建一个map
        m := make(map[string]int)
        m["one"] = 1
        m["two"] = 2
        fmt.Println(m)           // map[one:1 two:2]
        fmt.Println(len(m))      // 2
        fmt.Println(m["one"])    // 1
        fmt.Println(m["unknow"]) // 0
    ​
        r, ok := m["unknow"]
        fmt.Println(r, ok) // 0 falsedelete(m, "one")
    ​
        m2 := map[string]int{"one": 1, "two": 2}
        var m3 = map[string]int{"one": 1, "two": 2}
        fmt.Println(m2, m3)
    }
    

    也可以用map字面值的语法创建map,同时还可以指定一些最初的key/value

    ages := map[string]int{
        "alice":   31,
        "charlie": 34,
    }
    

    但是map中的元素并不是一个变量,不能对map的元素进行取址操作(禁止对map元素取址的原因是map可能随着元素数量的增长而重新分配更大的内存空间,从而可能导致之前的地址无效)

    _ = &ages["bob"] // compile error: cannot take address of map element
    
  • 结构体

    由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员

    type user struct {
        name     string
        password string
    }
    var u user
    

    当修改结构体的数据时,需要传入结构体的指针,进行修改

    type user struct {
        name     string
        password string
    }
    func (u user) checkPwd(password string) bool {
        return u.password == password
    }
    func (u *user) modifyPwd(password string) {
        u.password = password
    }
    func myPrint(flag bool) {
        if flag {
            println("比较成功")
        } else {
            println("比较失败")
        }
    }
    ​
    func main() {
        u := user{name: "hzy", password: "abc123"}
        flag := u.checkPwd("wakuwaku")
        
        myPrint(flag)
        u.modifyPwd("wakuwaku")
        println(u.password)
    }
    
  • 错误处理

    通过errors.New("xxx")创建新的错误

    func add(num1, num2 int) (res int, e error) {
        res = num1 + num2
        return res, errors.New("错误")
    }
    ​
    func main(){
        res, _ := add(1, 2)
        println(res)
    }