一、make

使用make可以创建切片,array、map、chan类型的数据。其返回的是引用类型。

创建切片:

  1. mSlice := make([]string, 3)
  2. mSlice[0] = "Dog"
  3. mSlice[1] = "Cat"
  4. mSlice[2] = "Tiger"
  5. fmt.Println(mSlice) // [Dog Cat Tiger]

创建Map:

mMap := make(map[int]string, 3)
mMap[10] = "Dog"
mMap[20] = "Cat"
mMap[30] = "Tiger"
fmt.Println(mMap) // map[10:Dog 20:Cat 30:Tiger]

创建通道(chan):

mChan := make(chan int)
close(mChan)

二、new

new返回传入类型的指针地址。
看一个示例:

nMap := new(map[int]string)
fmt.Println(nMap)
fmt.Println(reflect.TypeOf(nMap))

输出:

&map[]
*map[int]string

可以看出,通过 new 方法出来的数据是一个指针类型的数据。

三、常见操作

len、cap

  • len:长度,支持的数据类型:string、array、slice、map、chan
  • cap:容量,支持的数据类型:slice、array、chan

make的第三个参数可以预指定切片的大小,但是随着append的扩容会动态增加:

    mSlice := make([]int, 1, 2)
    mSlice[0] = 1
    fmt.Println(len(mSlice), cap(mSlice)) // 1 2

    mSlice = append(mSlice, 2)
    mSlice = append(mSlice, 3)
    fmt.Println(len(mSlice), cap(mSlice)) // 3 4

可以看出,每次append越界后,容量总是以make第三个参数指定的容量进行扩容。

close

使用 close 关闭一个通道。

    mChan := make(chan int, 1) // 创建一个通道
    mChan <- 1 // 往channel中写数据
    close(mChan) // 关闭channel

如果怕害怕记最后写关闭通道的代码,可以将其放于前面,加上 defer 修饰,这样在代码执行到最后的时候都会执行关闭通道的操作:

    mChan := make(chan int, 1)
    defer close(mChan)
    mChan <- 1

append

append方法往切片中添加一个或多个元素。

mSlice := make([]string, 1)
mSlice[0] = "dog"
mSlice = append(mSlice, "cat", "tiger")
fmt.Println(mSlice) // [dog cat tiger]
fmt.Println(len(mSlice)) // 3
fmt.Println(cap(mSlice)) // 3

len 方法返回切片的长度,cap 方法返回切片的容量。

copy

copy 可以往目标切片中拷贝一个已存在的切片。

mSlice := make([]string, 1)
mSlice[0] = "dog"
mSlice = append(mSlice, "cat", "tiger")

mSlice2 := make([]string, 2)
copy(mSlice2, mSlice)

fmt.Println(mSlice2) // [dog cat]

注意到,目标切片的长度设置为2,即使源切片长度为3,拷贝过来的仍然只有两个数据。

delete

delete 会删除map中指定key的元素

mMap := make(map[int]string)
mMap[10] = "dog"
mMap[20] = "cat"
delete(mMap, 10)
fmt.Println(mMap) // map[20:cat]

四、异常处理

在go语言中,使用 panicrecover 处理异常。
panic负责抛出异常:

func main() {
    panicRecover()
}

func panicRecover() {
    panic("I am panic")
}

执行后,控制台可以看到异常信息:
image.png

使用 recover 可以捕获异常:

func main() {
    panicRecover()
}

func panicRecover() {
    defer func() {
        msg := recover()
        fmt.Println(msg)
    }()
    panic("I am panic")
}

可以看到,控制台不报错了,只是打印出了异常信息:
image.png

panic 的封装,用于处理多种类型的异常:

func main() {
    panicRecover()
}

func panicRecover() {
    defer coverPanic()
    // 创建一个error类型的异常
    panic(errors.New("I am a pannic!"))
}

func coverPanic() {
    msg := recover()
    switch msg.(type) {
    case string:
        fmt.Println("string panic: ", msg)
    case error:
        fmt.Println("error panic: ", msg)
    default:
        fmt.Println("unknown panic: ", msg)
    }
}