go 的形参

注意

记录一个 go 语言编程中,可能不小心忽略的一个点,

  • 当函数的 出参 如果是 数组、结构体、 类型时,是不需要声明的,可以直接使用。

  • 但是如果 出参指针 类型(结构体指针或者map类型),则必须要显示的声明

代码示例

type person struct {
	name string
}

func main() {
	r := getList()
	fmt.Println(r)
	m := getMap()
	fmt.Println(m)
	p := getPerson()
	fmt.Println(p)
	// 会报错
	pp := getPointer()
	fmt.Println(pp)
}

func getList() (l []int) {
	for i := 0; i < 10; i++ {
		l = append(l, i)
	}
	return l
}

func getMap() (m map[int]int) {
	for i := 0; i < 5; i++ {
		m[i] = i
	}
	return m
}

func getPerson() (p person) {
	p.name = "张三"
	return p
}
func getPointer() (p *person) {
	p.name = "张三"
	return p
}

为什么指针需要声明呢?

  • 返回值是结构体时,编译器自动初始化一个空结构体;
  • 返回值是指针时,编译器只初始化一个 nil 指针,需要你手动 new() 或 &{}。

为什么返回切片不需要声明呢?

例如:

func add() (a []int) {
	a = append(a, 100)
	return a
}

这是因为,go的底层逻辑

当 a 是 nil(或容量不够)时,append 自动调用了 make() 分配新底层数组;然后返回新的 slice;再赋值给 a。

go的底层进行了如下判断(伪代码)

if cap(a) == 0 {
    newSlice := make([]int, len(a)+1)
    copy(newSlice, a)
    newSlice[len(a)] = 100
    return newSlice
}

所有上面代码的逻辑等价于

func add() (a []int) {
    a = make([]int, 0) // append 自动帮你做了这件事
    a = append(a, 100)
    return a
}

posted @ 2022-12-12 01:14  沧海一声笑rush  阅读(60)  评论(0)    收藏  举报